squish
squish

Reputation: 1116

Firestore keeps trying to setup emulators when it's already running in Next.js app

Has anyone ran into troubles with firebase and its emulators? I keep getting the following error on hot reload.

FirebaseError: Firestore has already been started and its settings can no longer be changed. You can only modify settings before calling any other methods on a Firestore object.

Initialisation:

// Initialize Firebase
const firebaseApp = initializeApp(firebaseConfig);

let mode = "emulate";

const auth = getAuth(firebaseApp);
const db = getFirestore(firebaseApp);
const storage = getStorage(firebaseApp);
const functions = getFunctions(firebaseApp);

if (mode === "emulate") {
  connectAuthEmulator(auth, "http://localhost:9099");
  connectFirestoreEmulator(db, "localhost", 8080);
  connectStorageEmulator(storage, "localhost", 9199);
  connectFunctionsEmulator(functions, "localhost", 5001);
}

export { firebaseApp, db, auth, storage, functions };

Upvotes: 0

Views: 1096

Answers (3)

rozky
rozky

Reputation: 2697

Had a similar problem and the following did the trick for me.

import { getApps } from 'firebase/app';

if (getApps().length === 0) {
   connectAuthEmulator(auth, "http://localhost:9099");
   connectFirestoreEmulator(db, "localhost", 8080);
   connectStorageEmulator(storage, "localhost", 9199);
   connectFunctionsEmulator(functions, "localhost", 5001);  
}

Upvotes: 0

Rafael Zasas
Rafael Zasas

Reputation: 993

I will add the solution from this post here as it worked for me.

Solution

    const EMULATORS_STARTED = 'EMULATORS_STARTED';
    function startEmulators() {
      if (!global[EMULATORS_STARTED]) {
        global[EMULATORS_STARTED] = true;
        firebase.firestore().useEmulator('localhost', <your_port>);
        firebase.auth().useEmulator('http://localhost:<your_port>/');
      }
    }
    
    if (process.env.NODE_ENV === 'development') {
      startEmulators();
    }

Note- If you are using Firebase V9:

const EMULATORS_STARTED = 'EMULATORS_STARTED';
function startEmulators() {
  if (!global[EMULATORS_STARTED]) {
    global[EMULATORS_STARTED] = true;
    connectFunctionsEmulator(functions, 'localhost', <your_port>);

    connectFirestoreEmulator(db, 'localhost', <your_port>);
  }
}

if (process.env.NODE_ENV === 'development') {
  startEmulators();
}

Reason:

The reason this needs to be done is that NextJS is trying to run the connect to the emulators many times over. This prevents emulators from connecting more than once.

Upvotes: 2

Seems useEmulator is called multiple times from the same browser instance. My suggestion is check this post in which the similar issue.

Upvotes: 1

Related Questions