Firebase App named ‘[DEFAULT]’ already exists with different options or config.

huangapple go评论60阅读模式
英文:

Firebase App named '[DEFAULT]' already exists with different options or config

问题

我正在使用NextJS、NextAuth和Firebase构建一个应用程序。

在实施NextAuth时,我遇到了这个错误:

错误 - FirebaseError:Firebase:Firebase应用程序名称为'[DEFAULT]'已经存在,具有不同的选项或配置(app/duplicate-app)。

以下是我的代码:

[...NextAuth].js

import NextAuth from "next-auth/next";
import GoogleProvider from "next-auth/providers/google";
import { FirestoreAdapter } from "@next-auth/firebase-adapter";

import { db } from "@/firebase/config";

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
  ],
  adapter: FirestoreAdapter(db),
});

我的Firebase配置文件

import { initializeApp, getApp, getApps } from "firebase/app";
import "firebase/auth";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
  apiKey: ___,
  authDomain: ___,
  projectId: ___,
  storageBucket: ___,
  messagingSenderId: ___,
  appId: ___,
  measurementId: ___,
};

const app =
  getApps().length === 0
    ? initializeApp({ ...firebaseConfig, projectId: firebaseConfig?.projectId })
    : getApp();
const db = getFirestore(app);

export { app, db };

正如您在我的配置文件中所看到的,我正在测试是否已经存在一个应用程序,但似乎不起作用。

我已经检查过是否有人遇到与我相同的问题,但没有找到答案。

有任何想法吗?

非常感谢,
Gabriel

英文:

I'm building an app with NextJS, NextAuth and Firebase.

While implementing NextAuth, I've encountered this error:

> error - FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists with different options or config (app/duplicate-app).

Here's my code:

<br/>

[...NextAuth].js

import NextAuth from &quot;next-auth/next&quot;;
import GoogleProvider from &quot;next-auth/providers/google&quot;;
import { FirestoreAdapter } from &quot;@next-auth/firebase-adapter&quot;;

import { db } from &quot;@/firebase/config&quot;;

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
  ],
  adapter: FirestoreAdapter(db),
});

My firebase config file

import { initializeApp, getApp, getApps } from &quot;firebase/app&quot;;
import &quot;firebase/auth&quot;;
import { getFirestore } from &quot;firebase/firestore&quot;;


const firebaseConfig = {
  apiKey: ___,
  authDomain: ___,
  projectId: ___,
  storageBucket: ___,
  messagingSenderId: ___,
  appId: ___,
  measurementId: ___,
};

const app =
  getApps().length === 0
    ? initializeApp({ ...firebaseConfig, projectId: firebaseConfig?.projectId })
    : getApp();
const db = getFirestore(app);

export { app, db };

As you can see in my config file, I'm testing if an app already exists, but it doesn't seem to work.

I've checked if somebody already had the same problem as me, but I didn't find an answer.

Any idea?

Thanks a lot,
Gabriel

答案1

得分: 0

根据NextAuth.js的Firebase适配器文档,您应该直接传递配置对象或从Admin SDK中获取Firestore的实例(即使用import { getFirestore } from "firebase-admin/firestore")。

最初,您应该尝试删除您的"@/firebase/config"导入,直接使用配置:

import NextAuth from "next-auth/next";
import GoogleProvider from "next-auth/providers/google";
import { FirestoreAdapter } from "@next-auth/firebase-adapter";

const firebaseConfig = {
  apiKey: ___,
  authDomain: ___,
  projectId: ___,
  storageBucket: ___,
  messagingSenderId: ___,
  appId: ___,
  measurementId: ___,
};

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
  ],
  adapter: FirestoreAdapter(firebaseConfig),
});

此初始化行为在src/index.ts中的主构造函数和src/utils.ts中的初始化实用程序方法中进行定义。 / packages / adapter-firebase / src / utils.ts#L141-L168)。

接下来要尝试的步骤是确保您的Next.js源码使用Firebase Admin SDK而不是行为不同的客户端Firebase SDK。

如果上述方法不起作用,您可以查找更一般的原因。浏览您的代码库,查找在您的代码引入"@/firebase/config"之前初始化Firebase服务提供程序的语句。在没有任何参数的情况下调用getApp()将悄悄初始化默认的FirebaseApp实例。

// 注意:这是伪代码,不是实际的实现
// 获取命名/默认应用程序,如果未初始化则引发错误
export function getApp(name: string = DEFAULT_ENTRY_NAME): FirebaseApp {
  const app = _apps.get(name);
  if (!app && name === DEFAULT_ENTRY_NAME) return initializeApp(); // <-- 这个initializeApp是问题的关键
  if (!app) throw an Error(name + " not initialized");
  return app;
}

这也适用于在没有应用程序参数的情况下初始化服务(例如getFirestore())的调用,因为它们也会在内部调用getApp()

// 注意:这是伪代码,不是实际的实现
export function getFirestore(app?: FirebaseApp) {
    app = app || getApp(); // 使用给定的应用程序或使用默认值
    return app._providers.get('firestore') || initializeFirestore(app, DEFAULT_SETTINGS);
}

不幸的是,追踪此特定问题可能会很麻烦,因为您的模块捆绑器/构建工具可能会“树摇”代码并剥离其认为不必要的部分,这可能包括您的getApp()getFirestore()调用,如果您在本地代码中不使用appdb。在这种情况下,只需使用import "@/firebase/config"应该可以解决问题。

英文:

According to the documentation for the Firebase Adapter for NextAuth.js, you should be passing in the configuration object to the adapter directly or an instance of Firestore from the Admin SDK (i.e. using import { getFirestore } from &quot;firebase-admin/firestore&quot;).

Initially, you should try removing your &quot;@/firebase/config&quot; import and just use the configuration directly.

import NextAuth from &quot;next-auth/next&quot;;
import GoogleProvider from &quot;next-auth/providers/google&quot;;
import { FirestoreAdapter } from &quot;@next-auth/firebase-adapter&quot;;

const firebaseConfig = {
  apiKey: ___,
  authDomain: ___,
  projectId: ___,
  storageBucket: ___,
  messagingSenderId: ___,
  appId: ___,
  measurementId: ___,
};

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
  ],
  adapter: FirestoreAdapter(firebaseConfig),
});

This initialization behaviour is defined in the main constructor in src/index.ts and in the initialization utility method in src/utils.ts.

The next step to try would be to make sure your Next.js sources make use of the Firebase Admin SDK instead of the client-side Firebase SDK which behaves differently.


If the above doesn't work, you can look for the more general cause. Sift through your codebase and look for statements that initialize Firebase service providers before your code pulls in &quot;@/firebase/config&quot;. Any call to getApp() without any arguments will silently initialize the default FirebaseApp instance.

// NOTE: this is pseudo-code, not the actual implementation
// gets the named/default app, throwing an error if not initialized
export function getApp(name: string = DEFAULT_ENTRY_NAME): FirebaseApp {
  const app = _apps.get(name);
  if (!app &amp;&amp; name === DEFAULT_ENTRY_NAME) return initializeApp(); // &lt;-- this initializeApp is your problem
  if (!app) throw new Error(name + &quot; not initialized&quot;);
  return app;
}

This also applies to calls that initialize a service (e.g. getFirestore()) without any app argument as they also will call getApp() internally.

// NOTE: this is pseudo-code, not the actual implementation
export function getFirestore(app?: FirebaseApp) {
    app = app || getApp(); // use given app or use default
    return app._providers.get(&#39;firestore&#39;) || initializeFirestore(app, DEFAULT_SETTINGS)
}

Unfortunately, tracking down this particular problem can be a pain as you module bundler/build tool might be "tree-shaking" the code and stripping what it thinks is unnecessary - which may include your getApp() and getFirestore() calls if you don't use app or db in the local code. Using just import &quot;@/firebase/config&quot; in this case should solve that.

huangapple
  • 本文由 发表于 2023年2月7日 01:44:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75364792.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定