Skip to content

fs_emulator_connect.js snippet doesn't work #283

@christiangenco

Description

@christiangenco

I'm following the Connect your app to the Cloud Firestore Emulator guide to try to make unit tests for my cloud functions.

After starting my emulator with npm run serve which runs firebase emulators:start --only functions,firestore,storage (and verifying that it works from the web interface) I tried to run this snippet:

import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";
// firebaseApps previously initialized using initializeApp()
const db = getFirestore();
connectFirestoreEmulator(db, 'localhost', 8080);

That code throws the error FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app/no-app)..

Alright fine I'll ignore the firebaseApps previously initialized using initializeApp() comment like another open issue noticed and initialize the app:

const { initializeApp } = require("firebase/app");
const {
  getFirestore,
  connectFirestoreEmulator,
} = require("firebase/firestore");

// firebaseApps previously initialized using initializeApp() and apparently they still do, too
initializeApp();
const db = getFirestore();
connectFirestoreEmulator(db, "localhost", 8080);

That code throws [FirebaseError: "projectId" not provided in firebase.initializeApp.]. Alright fine I'll change initializeApp() to initializeApp({ projectId: "anything-can-go-here" }) and now the code isn't crashing.

Sweet! Seems like we're getting somewhere. Let's add some code to try to actually write something to the database...

const { initializeApp } = require("firebase/app");
const {
  getFirestore,
  connectFirestoreEmulator,
  doc,
  setDoc,
} = require("firebase/firestore");

initializeApp({ projectId: "emulator" });
const db = getFirestore();
connectFirestoreEmulator(db, "localhost", 8080);

async function main() {
  const ref = doc(db, "tests/foo");
  const res = await setDoc(ref, { foo: "bar" });
  console.log({ res, ref });
}
main();

But now that throws FirebaseError: 7 PERMISSION_DENIED: No matching allow statements even though my firestore.rules is totally open:

rules_version = '2';

service cloud.firestore {
  match /databases/{database} {
    allow read, write: if true;
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

I found an old related issue that seems to be saying that throwing PERMISSION_DENIED is expected behavior unless you're authenticating as an admin, which you can emulate by passing an "Authorization: Bearer owner" header, but the code to do that looks nothing like in this snippet so I don't know how to integrate it. Maybe I can pass customHeaders into getFirestore? Who knows!

In any case, I don't think this snippet works as it's written.

What's a working example of connecting to the firestore emulator from node?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions