firebase-admin-node icon indicating copy to clipboard operation
firebase-admin-node copied to clipboard

`Firebase.initializeApp` throwing `default Firebase app already exists` errors in Next.js apps.

Open jstncno opened this issue 2 years ago • 17 comments

Describe your environment

  • Operating System version: macOS 12.6.3
  • Firebase SDK version: "firebase-admin": "^11.5.0"
  • Firebase Product: Admin SDK Firebase.initializeApp
  • Node.js version: v18.14.2
  • NPM version: 9.5.0

Describe the problem

Using Next.js SSR with Firebase consequently calls methods that call Firebase.initializeApp multiple times. This causes the following error to be thrown:

error - FirebaseAppError: The default Firebase app already exists. This means you called initializeApp() more than once without providing an app name as the second argument. In most cases you only need to call initializeApp() once. But if you do want to initialize multiple apps, pass a second argument to initializeApp() to give each app a unique name.

This issue is related to https://github.com/firebase/firebase-admin-node/issues/571#issue-457192854, but the resolution is not helpful and the supplied link (https://firebase.google.com/docs/reference/admin/node/admin.app.App.html#name) results in a 404.

Steps to reproduce:

Create a Next.js app using Server Side Rendering (SSR)

Workaround

I found a workaround by first checking if I've already initialized any apps before calling initializeApp() again:

if (!getApps().length) initializeApp();

jstncno avatar Mar 15 '23 16:03 jstncno

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.

google-oss-bot avatar Mar 15 '23 16:03 google-oss-bot

I meet the exact same issue. Just use nextjs and it will trigger this issue

bxclib2 avatar Jun 17 '23 11:06 bxclib2

I had the same issue with Next 13, in order to fix it I did this workaround:

import { getApps, initializeApp } from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";

const alreadyCreatedAps = getApps();
const yourFirebaseAdminConfig= {}

const App =
  alreadyCreatedAps.length === 0
    ? initializeApp({yourFirebaseAdminConfig}, "app name")
    : alreadyCreatedAps[0];

Describe your environment:

  • Operating System: Windows 11
  • Node.js version: v18.16.1
  • NPM version: 9.5.1
  • "firebase-admin": "^11.10.0"
  • "next": "13.4.8"

MauricioBorawski avatar Jul 14 '23 21:07 MauricioBorawski

Thank you for this clever solution

CSharpTeoMan911 avatar Aug 03 '23 22:08 CSharpTeoMan911

thanks for this...Next.js 13 has a lot of issues

Kingbonwa1994 avatar Aug 14 '23 13:08 Kingbonwa1994

Thanks to @MauricioBorawski 's solution, I was able to remove the error while HMR. However, when i run pnpm dev or pnpm build, FirebaseAppError: The default Firebase app does not exist. happened. With some workaround, I found following code snippet works

const yourFirebaseAdminConfig= {};

if (admin.apps.length === 0) {
  admin.initializeApp({ yourFirebaseAdminConfig });
}

Describe your environment:

  • Operating System: MacOS 14.1.1
  • Node.js version: v18.18.2
  • PNPM version: 8.11.0
  • "firebase-admin": "^12.0.0"
  • "next": "14.0.4"

mogulist avatar Jan 11 '24 08:01 mogulist

I'm not sure this solution works, as far as I can tell. It will work on the dev environment, but once deployed Firebase will complain that the app needs to be initialized first. I think that conditional causes problems. By extension, I've had to make code changes to deploy the app.

jessejamesrich avatar Jan 26 '24 19:01 jessejamesrich

I'm not sure this solution works, as far as I can tell. It will work on the dev environment, but once deployed Firebase will complain that the app needs to be initialized first. I think that conditional causes problems. By extension, I've had to make code changes to deploy the app.

@jessejamesrich How did you do for production? i am getting this error after deployment : FirebaseAppError: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.

marcellintacite avatar Jan 30 '24 16:01 marcellintacite

On dev I have to use the conditional to check if app exists (!admin.app.length) to make sure admin.initializeApp doesn't run again, but I have to comment out the conditional before deploying as Firebase seems to fail if (I assume) the first process run isn't admin initialization.

This is the best I can figure. It works, but I means you have to make changes to the code before deploying and then back again to get dev working. Here's what it looks like.

// if (!admin.apps.length) {
admin.initializeApp({
	credential: admin.credential.cert(serviceAccount as admin.ServiceAccount),
});
// }

jessejamesrich avatar Jan 30 '24 17:01 jessejamesrich

Olá, estou enfrentando o mesmo problema.

Estou usando o cron job da Vercel, eu uso o firestore do firebase e a terefa do cron é deletar dados em determinado horário.

Nisso eu preciso usar o admin SDK do google cloud para conseguir ter acesso ao firestore e excluir os dados.

Porém, em produção quando tento chamar minha função cron job exemplo: https://sitename/api/cron, nada acontece.

ja em desenvolvimento funciona perfeitamente.

Quem encontrar alguma solução poderia me ajudar?

rafaelbarross avatar Feb 16 '24 19:02 rafaelbarross

m produção quando ten

Still having this issue?

What's your logs for the https://sitename/api/cron call ?

Regards

All-Khwarizmi avatar May 09 '24 08:05 All-Khwarizmi

one solution that seemed to work is calling initializeApp with the config passed to it from a different file, like an entry file that loads right after the app loads, (e.g. layout file of nextjs), I know this might not be the optimal solution but it works.

OtmaniCodes avatar Jun 17 '24 20:06 OtmaniCodes

Here's a one-liner that works for me:

import { getApps, initializeApp, } from 'firebase-admin/app'
export const app = getApps()[0] || initializeApp({})

mrchantey avatar Jun 21 '24 02:06 mrchantey

Here's a one-liner that works for me:

import { getApps, initializeApp, } from 'firebase-admin/app'
export const app = getApps()[0] || initializeApp({})

Where do you put this one-liner?

OtmaniCodes avatar Jun 25 '24 21:06 OtmaniCodes

Where do you put this one-liner?

I just make a file called firebase.ts, for instance when running on the server:

//firebase.ts
import { getApps, initializeApp } from 'firebase-admin/app'
import { getFirestore } from 'firebase-admin/firestore'

// do emulator checks and stuff here

export const serverFirebaseApp = getApps()?.[0] || initializeApp({})

export const serverFirestore = getFirestore(serverFirebaseApp)

And only ever reference these exports when using firebase:

//elsewhere.ts

import {serverFirebaseApp, serverFirestore} from './firebase'

mrchantey avatar Jun 26 '24 02:06 mrchantey

I have done all the above steps still getting the error Steps ->

var admin = require("firebase-admin");
var serviceAccount = require("./utils/xyz-firebase-adminsdk-viiab-3435b36483.json");
if (!admin.apps.length) {
    const firebaseAdmin = admin.initializeApp({
        credential: admin.credential.cert(serviceAccount),
        databaseURL: "dB_URL"
    });
}

Error ->

errorInfo: { code: 'app/duplicate-app', message: 'The default Firebase app already exists. This means you called initializeApp() more than once without providing an app name as the second argument. In most cases you only need to call initializeApp() once. But if you do want to initialize multiple apps, pass a second argument to initializeApp() to give each app a unique name.' }, codePrefix: 'app' }

Dkathayat avatar Jul 31 '24 08:07 Dkathayat