【问题标题】:React NextJS Firebase error refresh Firebase App named '[DEFAULT]' already existsReact NextJS Firebase 错误刷新名为“[DEFAULT]”的 Firebase 应用程序已存在
【发布时间】:2023-03-31 14:48:02
【问题描述】:

我启动了一个项目,在多个组件中导入 firebase 时出错。

在这个 firebase 启动文件中:

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

然后在组件中:

import firebase from '../lib/firebaseClient'

使用单个组件效果很好,但如果我添加一个新组件:

import firebase from '../lib/firebaseClient' 

申请失败:

FirebaseError:Firebase:名为“[DEFAULT]”的 Firebase 应用已存在 (app/duplicate-app)。

【问题讨论】:

  • 您应该在您的应用程序初始化/引导方法中调用initializeApp(),这样它只会执行一次。不知道为什么 react/next 不止一次地完全调用导入;似乎是一个糟糕的模型,而且他们会以更有用的方式解决这个问题,所以在 react/next 方面也可能有解决方案。

标签: reactjs firebase next.js


【解决方案1】:

我有同样的问题,然后我发现了这个:

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

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

【讨论】:

    【解决方案2】:

    解决办法:

    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
    

    【讨论】:

      【解决方案3】:

      我的理解是该错误是由于为您的数据库多次调用 initializeApp() 造成的。扫描您的代码以确保您只调用一次 initializeApp()。对我来说,这包括检查任何可能调用该方法的 js 文件以及检查 html 文件中是否存在重复的 js 文件。

      我最近在自己的代码中解决了这个错误。我的问题是由于在我的 html 文件的头部和正文中意外链接了调用 initializeApp() 的 javascript 文件引起的。我的解决方法是删除我的 html 文件头部中重复的 javascript 标记,因此正文中只存在一个。

      【讨论】:

        【解决方案4】:

        在服务器端这样的东西应该可以工作

        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),
          });
        }
        

        【讨论】:

          【解决方案5】:

          总结所有好的答案。 更好的解决方法是将环境变量从 .env.local 加载到 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=
          

          接下来,我们可以像这样在客户端初始化 Firebase SDK。

          //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;
          

          最后,将 Firebase deps 导入其他文件。

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

          【讨论】:

            【解决方案6】:

            因此,由于 Next 的热重载的某些方面,我遇到了这个问题。我使用如下代码来确保我不会多次调用initializeApp

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

            这不起作用,因为似乎热重新加载正在清除 adminClient,所以我一直尝试调用 initializeApp,尽管 firebase 仍然记录了正在初始化的应用程序。

            为了解决这个问题,我使用了以下 sn-p:

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

            在新的服务器启动或由于开发中的代码更改而热重载时工作。

            【讨论】:

              【解决方案7】:

              如果您使用的是新的 Modular SDK v9.0.1,那么它可能不支持“firebase”命名空间。

              我使用的实现

              
                  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
              
              

              参考:

              • 堆栈溢出:Visit
              • Firebase 文档:Visit
              • Firebase 教程设置:Visit

              【讨论】:

              • 这肯定不对吧?如果 getApps 返回一些东西,你不需要跳过初始化吗?
              猜你喜欢
              • 1970-01-01
              • 2021-03-28
              • 2019-10-26
              • 2022-06-22
              • 2019-05-22
              • 1970-01-01
              • 1970-01-01
              • 2017-09-05
              相关资源
              最近更新 更多