Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6.3.4] Firebase: Firebase service named 'database' already registered (app/duplicate-service) #2054

Closed
youngvz opened this issue Aug 5, 2019 · 19 comments

Comments

@youngvz
Copy link

youngvz commented Aug 5, 2019

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, #2040, but was not able to resolve the issues by following those steps.

@google-oss-bot
Copy link
Contributor

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

@Feiyang1
Copy link
Member

Feiyang1 commented Aug 5, 2019

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());

@lookfirst
Copy link

lookfirst commented Aug 7, 2019

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.

@Feiyang1
Copy link
Member

Feiyang1 commented Aug 7, 2019

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'
...

@Mcebrera
Copy link

Mcebrera commented Aug 7, 2019

@Feiyang1 I'm assuming you need to have the latest firebase and firebase-admin via your comment #1696 (comment)

@lookfirst
Copy link

@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.

@lookfirst
Copy link

lookfirst commented Aug 7, 2019

@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

@Feiyang1
Copy link
Member

Feiyang1 commented Aug 7, 2019

@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?

@lookfirst
Copy link

@Feiyang1 latest

import 'firebase/auth'; worked, but now I get this warning from tslint:

WARNING: - import with explicit side-effect

@lookfirst
Copy link

This is nuts to have to wrangle imports like this to get things working. Where exactly is this documentation you speak of?

@lookfirst
Copy link

Found the docs. You have to click on the nodejs tab to see it: https://firebase.google.com/docs/web/setup

@Feiyang1
Copy link
Member

Feiyang1 commented Aug 7, 2019

Great! You can safely ignore the warning.firebase uses side-effect imports.

@Mcebrera
Copy link

Mcebrera commented Aug 7, 2019

@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?

@lookfirst
Copy link

/* tslint:disable:no-import-side-effect */
import 'firebase/auth';

@Feiyang1
Copy link
Member

Feiyang1 commented Aug 7, 2019

@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.

@Mcebrera
Copy link

Mcebrera commented Aug 7, 2019

@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.

@youngvz
Copy link
Author

youngvz commented Aug 7, 2019

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.

@youngvz
Copy link
Author

youngvz commented Aug 14, 2019

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.

@Feiyang1
Copy link
Member

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.

@firebase firebase locked and limited conversation to collaborators Oct 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants