Martín Varela
Martín Varela

Reputation: 53

React NextJS Firebase error refresh Firebase App named '[DEFAULT]' already exists

I started a project and occurred an error when importing firebase in more than one component.

In this firebase start file:

import firebase from 'firebase'
const firebaseConfig = {
  apiKey: "fdsfsdfdsf",
  authDomain: "fdsfdsfsdfdsf",
  databaseURL: "sdfdsfdsf",
  projectId: "dsfdsfdsf",
  storageBucket: "dsfdsfdsf",
  messagingSenderId: "dsfdsfsdfdsf"
}

const FbApp = firebase.initializeApp(firebaseConfig)

export default FbApp.auth()

Then in the components:

import firebase from '../lib/firebaseClient'

With a single component works well, but if I add a new component with:

import firebase from '../lib/firebaseClient' 

The application fail:

FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).

Upvotes: 2

Views: 4928

Answers (9)

Dmitrii Tkachenko
Dmitrii Tkachenko

Reputation: 586

In case you have several apps, this solution will work better:

import admin from 'firebase-admin';

const ADMIN_APP = 'ADMIN_APP';

const getFirebaseAdminAuth = () => {
  if (admin.apps.find((app) => app?.name === ADMIN_APP)) {
    return admin.app(ADMIN_APP);
  }

  return admin.initializeApp(
    {
      credential: admin.credential.cert({
        projectId: process.env.FIREBASE_PROJECT_ID,
        privateKey: process.env.FIREBASE_PRIVATE_KEY,
        clientEmail: process.env.FIREBASE_CLIENT_EMAIL
      })
    },
    ADMIN_APP
  );
};

export const auth = getFirebaseAdminAuth().auth();

Works for a standalone app as well.

Upvotes: 0

Niket Tongare
Niket Tongare

Reputation: 632

If you are using the Firebase admin in Next-JS you can try following

import { initializeApp, getApp, getApps , App } from 'firebase-admin/app';
import { getFirestore } from 'firebase-admin/firestore';

export const app: App = getApps().length ?  getApp() : initializeApp();
export const firestore = getFirestore(app);

This is typescript implementation. you can convert it to JS

UPDATED ON: 1-06-2023

Upvotes: 1

Sandeep Shaw
Sandeep Shaw

Reputation: 1

If you are using a new Modular SDK v9.0.1 then it might not support the "firebase" namespace.

The Implementation, I used


    import { initializeApp, getApps } from "firebase/app"
    import { getFirestore } from "firebase/firestore"
    import { getAuth } from "firebase/auth"
    
    
    //App configure
    const firebaseConfig = {
        apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
        authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
        projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
        storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
        messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGGING_SENDER_ID,
        appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
        measurementId: process.env.NEXT_PUBLIC_MEASUREMENT_ID
    };
    
    if (!getApps().length) {
      console.log(`...`)
    }
    
    const app = initializeApp(firebaseConfig)
    const db = getFirestore(app)
    const auth = getAuth(app)
    
    export {db, auth}
    export default app

Reference:

Upvotes: -1

James Quinlan
James Quinlan

Reputation: 1

So I ran into this issue because of some aspect of Next's hot reloading. I was using code like the following to ensure that I didn't call initializeApp more than once:

export let adminClient;
adminClient = adminClient || admin.initializeApp({...});

This didn't work because it seemed like the hot reloading was clearing adminClient, so I kept trying to call initializeApp, even though firebase still had the app recorded as being initialized.

To fix this, I used the following snippet:

const getAppInstance = () => {
    if (admin.apps.length) {
        return admin.apps[0];
    } else {
        return initApp();
    }
}

export const adminClient = getAppInstance();

which works on a fresh server start, or when hot reloading due to code changes in development.

Upvotes: 0

Penny Liu
Penny Liu

Reputation: 17428

Summarizing all good answers. A better fix would be to load environment variables from .env.local into process.env.

//.env.local
NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=

Next up, we can initialize the Firebase SDK on the client-side like this.

//shared/configs/firebase.js
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

const clientCredentials = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};

if (!firebase.apps.length) {
  firebase.initializeApp(clientCredentials);
}

export default firebase;

Finally, import the Firebase deps to other file.

//pages/index.js
import firebase from '../shared/configs/firebase';

Upvotes: 0

Mathias Asberg
Mathias Asberg

Reputation: 3840

On serverside something like this should work

const admin = require('firebase-admin');
const serviceAccount = require('./../../credentials/server');

// Check if firebase already been initialized
if (!admin.apps.length) {
  // Initialize Firestore.
  admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
  });
}

Upvotes: 0

Meet Zaveri
Meet Zaveri

Reputation: 3059

I had same issue, then I found out this:

if (!firebase.apps.length) {
  firebase.initializeApp({});
}

https://github.com/zeit/next.js/issues/1999

Upvotes: 10

kendra
kendra

Reputation: 21

My understanding is that the error is due to calling initializeApp() more than once for your database. Scan through your code to make sure you only call initializeApp() once. For me, this included checking any js files that might be calling the method and checking for duplicate js files in your html file.

I recently solved this error in my own code. My issue was caused by accidentally linking my javascript file, which calls initializeApp(), in the head and in the body of my html file. My fix was to delete the duplicate javascript tag in the head of my html file so only one existed in the body.

Upvotes: 0

Martín Varela
Martín Varela

Reputation: 53

The solution:

import firebase from 'firebase'

try {
  firebase.initializeApp({
    databaseURL: 'dfgdfg'
  })
} catch (err) {
  // we skip the "already exists" message which is
  // not an actual error when we're hot-reloading
  if (!/already exists/.test(err.message)) {
    console.error('Firebase initialization error', err.stack)
  }
}

const auth = firebase.auth()
export default auth

Upvotes: 3

Related Questions