Skip to content

Database tries to call connectDatabaseEmulator when already initialized, leading to FIREBASE FATAL ERROR #6853

@Janque

Description

@Janque

[REQUIRED] Describe your environment

  • Operating System version: MacOS Monterrey 12.6
  • Browser version: Google Chrome 108.0.5359.94
  • Firebase SDK version: 9.14.0
  • Firebase Product: database

[REQUIRED] Describe the problem

Steps to reproduce:

I'm using the nextjs integration with firebase database and when there is a hot reload (ex. saving a file), the following error appears: Error: FIREBASE FATAL ERROR: Cannot call useEmulator() after instance has already been initialized.
From the line:

 export const database = getDatabase(firebaseApp);

When there has been no hot reload, everything works fine.

After more investigation I found that the code that connects the emulator differs from the one that connects the firebase emulator

//firebase-js-sdk/packages/firestore/src/api/database.ts
export function getFirestore(
  appOrDatabaseId?: FirebaseApp | string,
  optionalDatabaseId?: string
): Firestore {
  const app: FirebaseApp =
    typeof appOrDatabaseId === 'object' ? appOrDatabaseId : getApp();
  const databaseId =
    typeof appOrDatabaseId === 'string'
      ? appOrDatabaseId
      : optionalDatabaseId || DEFAULT_DATABASE_NAME;
  const db = _getProvider(app, 'firestore').getImmediate({
    identifier: databaseId
  }) as Firestore;
  if (!db._initialized) {
    const emulator = getDefaultEmulatorHostnameAndPort('firestore');
    if (emulator) {
      connectFirestoreEmulator(db, ...emulator);
    }
  }
  return db;
}
//firebase-js-sdk/packages/database/src/api/Database.ts
export function getDatabase(
  app: FirebaseApp = getApp(),
  url?: string
): Database {
  const db = _getProvider(app, 'database').getImmediate({
    identifier: url
  }) as Database;
  //In line 323 should be added if(!db._instanceStarted){
    const emulator = getDefaultEmulatorHostnameAndPort('database');
    if (emulator) {
      connectDatabaseEmulator(db, ...emulator);
    }
  //}
  return db;
}
//...
export function connectDatabaseEmulator(
  db: Database,
  host: string,
  port: number,
  options: {
    mockUserToken?: EmulatorMockTokenOptions | string;
  } = {}
): void {
  db = getModularInstance(db);
  db._checkNotDeleted('useEmulator');
  if (db._instanceStarted) {  //This check becomes redundant
    fatal(
      'Cannot call useEmulator() after instance has already been initialized.'
    );
  }
  //...
}

I believe that those changes would fix the issue.

My package.json dependencies

"dependencies": {
    "@fortawesome/fontawesome-svg-core": "^6.2.0",
    "@fortawesome/free-brands-svg-icons": "^6.2.0",
    "@fortawesome/free-solid-svg-icons": "^6.2.0",
    "@fortawesome/react-fontawesome": "^0.2.0",
    "bootstrap": "4.6.2",
    "firebase": "^9.14.0",
    "firebaseui": "^6.0.1",
    "jquery": "^3.6.1",
    "next": "^13.0.2",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "sass": "^1.55.0"
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions