React NextJS Firebase 错误刷新名为“[DEFAULT]”的 Firebase 应用程序已存在

Posted

技术标签:

【中文标题】React NextJS Firebase 错误刷新名为“[DEFAULT]”的 Firebase 应用程序已存在【英文标题】:React NextJS Firebase error refresh Firebase App named '[DEFAULT]' already exists 【发布时间】:2017-10-17 11:55:32 【问题描述】:

我启动了一个项目,在多个组件中导入 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 方面也可能有解决方案。 【参考方案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 返回一些东西,你不需要跳过初始化吗?

以上是关于React NextJS Firebase 错误刷新名为“[DEFAULT]”的 Firebase 应用程序已存在的主要内容,如果未能解决你的问题,请参考以下文章

为啥我从托管在 Firebase 上的 NextJs 应用程序仅针对 POST 请求收到“502 网关”错误?

React/NextJS 使用 UseEffect 错误:渲染的钩子比上一次渲染期间更多

Firebase 存储图像未显示在 nextjs 应用程序中

带有 Chakra UI 的 React-hook-form 未在 NextJS 中显示验证错误消息

React/nextJS:如何调试 s-s-r react 应用的不同节点?

升级到 NextJS 9.0 后如何修复 React Hooks?