Skip to content

Can't use multiple RTDB instances with emulator #3681

@rhodgkins

Description

@rhodgkins

[REQUIRED] Describe your environment

  • Operating System version: macOS 10.15.6 (19G73)
  • firebase-admin SDK version: 9.1.1
  • firebase-tools version: 8.9.0
  • @firebase/database version: 0.6.11
  • RTDB emulator version: 4.5.0
  • Firebase Product: database, testing-sdk
  • Node.js version: 14.8.0

[REQUIRED] Describe the problem

When using multiple database instances (via app.database(URL)) with the firebase-tools emulator errors are thrown.

Steps to reproduce:

const { app } = require('firebase-admin')

const _app = require('firebase-admin').initializeApp({
   databaseURL: 'https://against-emulator.firebaseio.com'
})

Promise.resolve(_app).then(async app => {
   const mainInstance = app.database()
   console.log('Main DB:', mainInstance['repo_']['repoInfo_'])
   const mainInstanceRef = mainInstance.ref('root')
   console.log('Main DB ref:', mainInstanceRef.toString())
   const otherInstance = app.database('https://against-emulator-other-instance.firebaseio.com')
   console.log('Other DB:', otherInstance['repo_']['repoInfo_'])
   const otherInstanceRef = otherInstance.ref('root')
   console.log('Other DB ref:', otherInstanceRef.toString())
})
   .catch(err => console.error('Error - ', err))
   .finally(() => _app.delete())

Run the above code with just node script.js and the following is outputted with no errors:

Main DB: RepoInfo {
  secure: true,
  namespace: 'against-emulator',
  webSocketOnly: false,
  persistenceKey: '',
  includeNamespaceInQueryParams: false,
  host: 'against-emulator.firebaseio.com',
  domain: 'firebaseio.com',
  internalHost: 'against-emulator.firebaseio.com'
}
Main DB ref: https://against-emulator.firebaseio.com/root
Other DB: RepoInfo {
  secure: true,
  namespace: 'against-emulator-other-instance',
  webSocketOnly: false,
  persistenceKey: '',
  includeNamespaceInQueryParams: false,
  host: 'against-emulator-other-instance.firebaseio.com',
  domain: 'firebaseio.com',
  internalHost: 'against-emulator-other-instance.firebaseio.com'
}
Other DB ref: https://against-emulator-other-instance.firebaseio.com/root

Now running against the DB emulator firebase emulators:exec --project against-emulator --only database 'node script.js', errors occur:

Main DB: RepoInfo {
  secure: false,
  namespace: 'against-emulator',
  webSocketOnly: false,
  persistenceKey: '',
  includeNamespaceInQueryParams: true,
  host: 'localhost:9000',
  domain: 'localhost:9000',
  internalHost: 'localhost:9000'
}
Main DB ref: http://localhost:9000/root
[2020-08-25T13:22:27.260Z]  @firebase/database: FIREBASE FATAL ERROR: Database initialized multiple times. Please make sure the format of the database URL matches with each database() call. 
Error -  Error: FIREBASE FATAL ERROR: Database initialized multiple times. Please make sure the format of the database URL matches with each database() call. 
    at fatal (<path>/node_modules/@firebase/database/dist/index.node.cjs.js:341:11)
    at RepoManager.createRepo (<path>/node_modules/@firebase/database/dist/index.node.cjs.js:15047:13)
    at RepoManager.databaseFromApp (<path>/node_modules/@firebase/database/dist/index.node.cjs.js:15014:25)
    at Object.initStandalone (<path>/node_modules/@firebase/database/dist/index.node.cjs.js:15389:45)
    at DatabaseService.getDatabase (<path>/node_modules/firebase-admin/lib/database/database-internal.js:82:23)
    at FirebaseApp.database (<path>/node_modules/firebase-admin/lib/firebase-app.js:232:24)
    at <path>/script.js:12:30

Relevant Code:

This is the bit of code throwing the error:

let repo = safeGet(appRepos, repoInfo.toURLString());
if (repo) {
fatal(
'Database initialized multiple times. Please make sure the format of the database URL matches with each database() call.'
);
}

It seems that RepoInfo#toURLString:

toURLString(): string {
return (this.secure ? 'https://' : 'http://') + this.host;
}

Doesn't take into account the namespace of the RepoInfo which the emulator uses to distinguish between different DB instances.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions