I'm trying to run the Firebase shell however I get the error:
FirebaseError: Firebase: Firebase service named 'database' already registered (app/duplicate-service).
My Firebase dependencies:
"firebase": "^6.3.4",
"firebase-admin": "^8.3.0",
"firebase-functions": "^3.0.2"
I initialize the Firebase in my index.js like:
admin.initializeApp(appConfig);
firebase.initializeApp(appConfig);
const rtdb = admin.database(admin.app());
const firestore = firebase.firestore(admin.app());
Possibly the same issue as, https://github.com/firebase/firebase-js-sdk/issues/2040, but was not able to resolve the issues by following those steps.
I found a few problems with this issue:
The message indicates you are have import 'firebase/database' in multiple places.
How do you import firebase, are you using import * as firebase from 'firebase'? It will import firebase/database implicitly.
Also It's incorrect to pass admin.app() into firebase.firestore(). It might just work because firestore is only looking at something admin.app() and firebase.app() share, but it's wrong, and you should do firebase.firestore(firebase.app());
I just went through my entire codebase and carefully made sure that I'm at the latest versions of all my google dependencies.
I fixed every single one of my imports to only import exactly what was needed. No more * as admin or * as firebase. Also no more import admin from 'firebase-admin'
All my imports look like this now:
import {https} from 'firebase-functions';
import {initializeApp as adminInitializeApp, credential, ServiceAccount} from 'firebase-admin'
import {initializeApp as firebaseInitializeApp} from "firebase";
I'm referencing database from my initialized app:
const FIREBASE_CONFIG = process.env.FIREBASE_CONFIG || {} as any;
const adminConfig = JSON.parse(FIREBASE_CONFIG);
adminConfig.credential = credential.cert(serviceAccount as ServiceAccount);
const firebaseClientApp = firebaseInitializeApp(clientAccount);
const firebaseAdminApp = adminInitializeApp(adminConfig);
firebaseAdminApp.database()...
I'm still getting this error...
> FirebaseError: Firebase: Firebase service named 'database' already registered (app/duplicate-service).
> at Object.registerService (/functions/node_modules/@firebase/app/dist/index.node.cjs.js:375:33)
> at registerDatabase (/functions/node_modules/@firebase/database/dist/index.node.cjs.js:15248:39)
> at Object.<anonymous> (/functions/node_modules/@firebase/database/dist/index.node.cjs.js:15271:5)
> at Module._compile (internal/modules/cjs/loader.js:776:30)
> at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
> at Module.load (internal/modules/cjs/loader.js:643:32)
> at Function.Module._load (internal/modules/cjs/loader.js:556:12)
> at Module.require (internal/modules/cjs/loader.js:683:19)
> at require (internal/modules/cjs/helpers.js:16:16)
> at DatabaseService.getDatabase (/functions/node_modules/firebase-admin/lib/database/database.js:64:24) {
> code: 'app/duplicate-service',
> name: 'FirebaseError',
> appName: 'database'
> }
There is no way to use both Admin SDK and Firebase JS SDK in firebase cloud functions with this error.
Don't use import {initializeApp as firebaseInitializeApp} from "firebase";
firebase package implicitly imports all components, so database is also imported (even though you didn't do it).
Import individual components you need like the following:
import * as firebase from 'firebase/app';
import 'firebase/firestore'
...
@Feiyang1 I'm assuming you need to have the latest firebase and firebase-admin via your comment https://github.com/firebase/firebase-js-sdk/issues/1696#issuecomment-516596556
@Feiyang1 I hate to tell you this, but requiring people to do specific imports is not going to work as a solution to this issue. Especially when there is zero documentation for it as well.
@Feiyang1
Ok, when I do what you suggested with the imports, I get a new runtime error from my initialized client app instance:
TypeError: firebaseClientApp.auth is not a function
Thus this does not work:
firebaseClientApp.auth().signInWithCustomToken
@Mcebrera Yes, the latest firebase and firebase-admin should work without the issue mentioned in the thread that you linked. You said it's not working for you. Do you face the same issue in this thread, or something else?
@lookfirst We highly discourage the usage of the all in one firebase package, as it will likely include component you don't need and bloat your app. We recently revamped the devsite to use individual imports in all our guides to guide developers.
What version of firebase and firebase-admin are you using? Do you have import "firebase/auth"?
If possible, can you share the whole import block?
@Feiyang1 latest
import 'firebase/auth'; worked, but now I get this warning from tslint:
WARNING: - import with explicit side-effect
This is nuts to have to wrangle imports like this to get things working. Where exactly is this documentation you speak of?
Found the docs. You have to click on the nodejs tab to see it: https://firebase.google.com/docs/web/setup
Great! You can safely ignore the warning.firebase uses side-effect imports.
@Feiyang1 At the time it wasn't working because I didn't know about the implicit imports of firebase package. I was still getting the database is already registered (app/duplicate) message on firebase deploy's
Going to try again... for the record I have my initial function code entry initializing the admin SDK:
const admin = require("firebase-admin");
admin.initializeApp({
credential: admin.credential.cert(firebaseServiceAccount),
databaseURL: "https://project-development.firebaseio.com/"
});
and then calling a function that initializes the firebase app inside of it.
const firebaseClient = require("firebase");
firebaseClient.initializeApp(config);
const ClientAuthService = firebaseClient.auth();
From what you're saying... I have to call firebase/auth for the initialization so it doesn't implicitly register my database as well?
/* tslint:disable:no-import-side-effect */
import 'firebase/auth';
@Mcebrera instead of require("firebase"), use:
require("firebase/app");
require("firebase/auth");
// and other components you need
It might be helpful to read the getting started guide.
@Feiyang1 Thank you I'll try that.
Something odd that just happened: I updated the firebase package to latest npm install --save firebase@latest in both my functions folder and another and the deploy worked. I didn't change any code... I'm happy but confused lol.
Changing const firebase = require('firebase') to const firebase = require('firebase/app') allows me to test and deploy my firebase functions. However, the firebase shell gets stuck when I try to locally emulate my functions when I run firebase functions:shell.
Ive gotten the local firebase functions emulator working again - if you are getting the name is undefined error then you will need to add a resource entry into the passed in context object (the one with the params on it).
Here is a full example:
onConfigEntryWrittenMigration({before: 1, after: 2}, {resource: {name: 'projects/_/instances/dev-neko/refs/{ref=**}'}, params: {configId: 'current_eula_version'}});
Run against dev database: resource: {name: 'projects/_/instances/dev-neko/refs/{ref=**}'}
Run against unit test database:resource: {name: 'projects/_/instances/dev-test-neko/refs/{ref=**}'}
If it is hanging once you run npm run start and never launching into the shell then you will need to do so manually:
From the terminal cd into the neko-firebase/functions folder
Run node - this will launch a node shell
Run const app = require('./index.js');
Now you can call any of the exported functions from the index.js file, same example as above:
app.onConfigEntryWrittenMigration({before: 1, after: 2}, {resource: {name: 'projects/_/instances/dev-neko/refs/{ref=**}'}, params: {configId: 'current_eula_version'}});
Not all that ideal, still looking for a better solution so let us know if you find one.
Update:
Error app/duplicate-service has been removed since 6.4.1. You won't get the error anymore when using firebase and firebase-admin together.
Most helpful comment
I just went through my entire codebase and carefully made sure that I'm at the latest versions of all my google dependencies.
I fixed every single one of my imports to only import exactly what was needed. No more
* as adminor* as firebase. Also no moreimport admin from 'firebase-admin'All my imports look like this now:
I'm referencing database from my initialized app:
firebaseAdminApp.database()...I'm still getting this error...
There is no way to use both Admin SDK and Firebase JS SDK in firebase cloud functions with this error.