ZYinMD
ZYinMD

Reputation: 5069

Writing tests against local firestore emulator using the admin SDK with no auth

Edit: it's essentially an issue of the firebase-emulator docs. See discussion here.


I'm trying to directly access a Firestore instance running on the local emulator with the nodejs admin SDK. Minimal example:

// test.js
const admin = require("firebase-admin"); // version 9.1.1
admin.firestore().collection('foo').add({ a: 1 });

Then just $ node test.js to see if it works.

The only doc I can find regarding this is this one sentence, which tells me to set an environmental variable, so I did, something like this:

$ FIRESTORE_EMULATOR_HOST='localhost:1003' node test.js

But I get an error message Unable to detect a Project Id in the current environment. But I am inside my filebase project folder. What am I missing? My eventual goal is to write unit tests to test my server code that uses firestore. The server is running on cloud functions, and currently I am able to trigger the function from within the test suites which can successfully read/write to the local DB, but that's too convoluted for writing tests.

firebase.json:

{
  ...
  "emulators": {
    "ui": {
      "enabled": true,
      "port": 1000
    },
    "hosting": {
      "port": 1001
    },
    "functions": {
      "port": 1002
    },
    "firestore": {
      "port": 1003
    }
  }
}

(I've tried each of these 4 ports, none worked)

Upvotes: 0

Views: 2109

Answers (3)

Chidex
Chidex

Reputation: 179

Actually, I agree with @akauppi's answer. This is a snippet from the firebase emulators docs:

When connecting to the Authentication emulator, you will need to specify a project ID. You can pass a project ID to initializeApp directly or set the GCLOUD_PROJECT environment variable. Note that you do not need to use your real Firebase project ID; the Authentication emulator will accept any project ID.

Upvotes: 1

akauppi
akauppi

Reputation: 18046

My experience is that the Firebase Emulators like being given a dummy project id. I use something like bunny in my projects, to make it seem funny.

Launch the emulator with:

$ firebase emulators:start --project=bunny --only auth,functions,firestore

The reality is more complicated, though. For a real world example, you can check out http://github.com/akauppi/GroundLevel-firebase-es

Upvotes: 1

vitooh
vitooh

Reputation: 4262

When emulator is run with command firebase emulators:start you will get ports for emulated features ex.:

 ───────────────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! View status and logs at http://localhost:4000 │
└───────────────────────────────────────────────────────────────────────┘
┌───────────┬────────────────┬─────────────────────────────────┐
│ Emulator  │ Host:Port      │ View in Emulator UI             │
├───────────┼────────────────┼─────────────────────────────────┤
│ Functions │ localhost:5001 │ http://localhost:4000/functions │
├───────────┼────────────────┼─────────────────────────────────┤
│ Firestore │ localhost:3000 │ http://localhost:4000/firestore │
└───────────┴────────────────┴─────────────────────────────────┘
  Other reserved ports: 4400, 4500
Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.

Than using the same link I created minimal example:

const admin = require("firebase-admin"); // version 9.1.1
admin.initializeApp();
var db = admin.firestore();
db.settings({
    host: "localhost:3000",
    ssl: false
});
admin.firestore().collection('foo').add({ a: 1 })
.then( (r) => console.log("document added: ",r.path) )
.catch( (e) => console.log("error: ",e) );

Note that first app instance has to be created with initializeApp method and than set the path to your emulator. However I guess there are many other ways to do this. If successful this will show path to created doc. I didn't use any additional setup.

Upvotes: 2

Related Questions