Firebase emulators with Next.js

Viewed 399

I'm trying to setup Firebase's V9 emulators with Next.js without any luck. I'm always getting this error, enter image description here

My firebase version is, 9.1.1.

My Firebase setup looks like this:

import { initializeApp, FirebaseApp } from "firebase/app";
import { initializeApp, FirebaseApp } from "firebase/app";
import firebase from "firebase/compat/app";
import { getAuth, connectAuthEmulator, Auth } from "firebase/auth";
import {
  getFirestore,
  connectFirestoreEmulator,
  Firestore,
} from "firebase/firestore";
import {
  getStorage,
  connectStorageEmulator,
  FirebaseStorage,
} from "firebase/storage";
import {
  getDatabase,
  connectDatabaseEmulator,
  Database,
} from "firebase/database";

let firebaseApp: FirebaseApp;
let auth: Auth;
let firestore: Firestore;
let storage: FirebaseStorage;
let db: Database;

if (!firebase.apps.length) {
  firebaseApp = initializeApp(clientCredentials);
  auth = getAuth(firebaseApp);
  firestore = getFirestore(firebaseApp);
  storage = getStorage(firebaseApp);
  db = getDatabase(firebaseApp);
}

if (IS_DEV) {
  connectFirestoreEmulator(firestore, "localhost", 8080);
  connectAuthEmulator(auth, "http://localhost:9099", { disableWarnings: true });
  connectDatabaseEmulator(db, "localhost", 9000);
  connectStorageEmulator(storage, "localhost", 9199);
}

export { firebaseApp, auth, firestore, storage, db }

I've made sure there's no calling of my firestore object. As soon as Next.js starts up, I get that error.

1 Answers

This is happening due to global namespace values and the NextJs runtime.

You can fix this as follows:

const EMULATORS_STARTED = 'EMULATORS_STARTED';
function startEmulators() {
  if (!global[EMULATORS_STARTED]) {
    global[EMULATORS_STARTED] = true;
    connectFunctionsEmulator(functions, 'localhost', 5001);
    connectFirestoreEmulator(db, 'localhost', 8080);
    connectAuthEmulator(auth, "http://localhost:9099", { disableWarnings: true });
    connectDatabaseEmulator(db, "localhost", 9000);
    connectStorageEmulator(storage, 'localhost', 9199);
  }
}

Firebase adds a global namespace of 'EMULATORS_STARTED' once it has started and NextJs attempts to run that code multiple times. This script will prevent you from attempting to connect to the emulators more than once.

Related