如何将来自不同组件的Firebase身份验证和Cloud Firestore用作单个Firebase应用

Joj*_*oji 9 javascript firebase reactjs google-cloud-firestore

我正在尝试在我的React项目中使用firebase提供身份验证和数据库功能。

在我App.js我有

import app from "firebase/app";
import "firebase/auth";
app.initializeApp(firebaseConfig);
Run Code Online (Sandbox Code Playgroud)

在我称为<Component />渲染的其他组件中,App.js我可以使用它来初始化数据库

import app from "firebase/app";
import "firebase/firestore";
const db = app.firestore();
Run Code Online (Sandbox Code Playgroud)

但是这次我得到这个错误

Uncaught FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app/no-app).
Run Code Online (Sandbox Code Playgroud)

因此,我也尝试加入app.initializeApp(firebaseConfig);此组件,但是又遇到了一个新错误,告诉我我实例化了两次。

Uncaught FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).
Run Code Online (Sandbox Code Playgroud)

因此,我想出的一种解决方法是在创建数据库App.js之后立即创建一个上下文,并将值传递给该上下文并使用。但是我不知道这是否是一个好的解决方案。app.initializeApp(firebaseConfig);const db = app.firestore();<Component />

我的问题与出于某种原因如何检查Firebase应用程序是否已在Android上初始化”不同。我并没有尝试连接到第二个Firebase应用程序,因为它是针对该问题的。我整个项目只有一个Firebase应用程序,可以提供两种服务:auth和数据库。

我尝试了该问题的解决方案以用于 <Component />

if (!app.apps.length) {
  app.initializeApp(firebaseConfig);
}

const db = app.firestore();
Run Code Online (Sandbox Code Playgroud)

但它不起作用,仍然给我Uncaught FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).错误

Val*_*rii 5

您在 App 和 Component 中使用不同的 Firebase 实例。

// firebaseApp.js
import firebase from 'firebase'
const config = {
    apiKey: "...",
    authDomain: "...",
    databaseURL: "....",
    projectId: "...",
    messagingSenderId: "..."
};
firebase.initializeApp(config);
export default firebase;
Run Code Online (Sandbox Code Playgroud)

比您可以从 firebaseApp.js 导入 firebase 并使用它。更多细节在这里


Sri*_*a K 5

在firebase 配置目录firebaseConfig.js中创建一个文件:src/firebase

import firebase from 'firebase/app'; // doing import firebase from 'firebase' or import * as firebase from firebase is not good practice. 
import 'firebase/auth';
import 'firebase/firestore';

// Initialize Firebase
let config = {
    apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
    authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
    databaseURL: process.env.REACT_APP_FIREBASE_DATABASE_URL,
    projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
    storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
};
firebase.initializeApp(config);

const auth = firebase.auth();
const db = firebase.firestore();

const googleAuthProvider = new firebase.auth.GoogleAuthProvider();
const emailAuthProvider = new firebase.auth.EmailAuthProvider();

export { auth, firebase, db, googleAuthProvider, emailAuthProvider };
Run Code Online (Sandbox Code Playgroud)

您所要做的Component.js就是:

import { db } from './firebase/firebaseConfig.js'; // Assuming Component.js is in the src folder
Run Code Online (Sandbox Code Playgroud)

将 api 密钥存储在.env项目根文件夹( 的父文件夹src)的文件中:

REACT_APP_FIREBASE_API_KEY=<api-key>
REACT_APP_FIREBASE_AUTH_DOMAIN=<auth-domain>
REACT_APP_FIREBASE_DATABASE_URL=<db-url>
REACT_APP_FIREBASE_PROJECT_ID=<proj-name>
REACT_APP_FIREBASE_STORAGE_BUCKET=<storage-bucket>
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=<message-sender-id>
Run Code Online (Sandbox Code Playgroud)


KpT*_*tor 2

您收到的错误消息是有效的,并且与模块的导入顺序有关。ES6 模块经过预解析,以便在执行代码之前解决进一步的导入问题。

假设你的顶部App.js看起来像这样:

import Component from '../component';
...

import app from "firebase/app";
import "firebase/auth";
app.initializeApp(firebaseConfig);
Run Code Online (Sandbox Code Playgroud)

这里的问题是里面import Component from '.../component';

import app from "firebase/app";
import "firebase/firestore";
const db = app.firestore();
Run Code Online (Sandbox Code Playgroud)

该代码会在您执行以下操作之前执行:

app.initializeApp(firebaseConfig);
Run Code Online (Sandbox Code Playgroud)

有很多方法可以解决这个问题,包括上面介绍的一些解决方案以及将 firebase 配置存储在 a 中firebase-config.js并从中导入的建议db

这个答案更多的是关于理解问题是什么......就解决方案而言,我认为你的解决方案Context Provider实际上非常好并且普遍实践。

有关 es6 模块的更多信息请参见此处

Firebase 反应设置

希望有帮助。