firebase Firestore错误-无法读取属性'firestore'为空

k3bvogb1  于 2022-12-30  发布在  其他
关注(0)|答案(2)|浏览(194)

我尝试在react项目中使用firestore,在认证后将一些数据写入firebase,但是每当调用doc.set时,我得到一个错误消息Cannot read property firestore of null
这是我的firebase配置文件。

import firebase from 'firebase/app';

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

if (firebase.apps.length === 0) {
  console.log('Initializing firebase');
  firebase.initializeApp(config);
}

export default firebase;

这是我的firebase utils文件,我用它来访问firebase的公共需求。

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

import {FIREBASE_COLLECTIONS} from './constants';

export const getIdToken = async () => {
  try {
    const {currentUser} = firebase.auth();
    if (currentUser) {
      const idToken = await currentUser.getIdToken();
      return idToken;
    }
    return currentUser;
  } catch (error) {
    throw error || new Error('Error retrieving ID token');
  }
};

export const logout = async () => {
  try {
    await firebase.auth().signOut();
  } catch (error) {
    throw error || new Error('Error logging out');
  }
};

export const loginUser = async (email: string, password: string) => {
  try {
    const user = await firebase
      .auth()
      .signInWithEmailAndPassword(email, password);
    return user;
  } catch (error) {
    let message = '';
    switch (error.code) {
      case 'auth/invalid-email':
        message = 'Invalid Email Id';
        break;
      case 'auth/user-disabled':
        message = 'User is temporarily disabled';
        break;
      case 'auth/user-not-found':
        message = 'User not found. Please register';
        break;
      case 'auth/wrong-password':
        message = 'Incorrect password';
        break;
      default:
        message = 'Error logging in';
        break;
    }
    throw new Error(message);
  }
};

export const registerUser = async (email: string, password: string) => {
  try {
    const user = await firebase
      .auth()
      .createUserWithEmailAndPassword(email, password);
    return user;
  } catch (error) {
    const errorCode = error.code;
    let message = '';
    switch (errorCode) {
      case 'auth/email-already-in-use':
        message = 'Email already in use';
        break;
      case 'auth/invalid-email':
        message = 'Invalid email ID';
        break;
      case 'auth/weak-password':
        message = 'Weak password';
        break;
      default:
        message = 'Error registering user';
        break;
    }
    throw new Error(message);
  }
};

export const signInWithGoogle = async () => {
  const provider = new firebase.auth.GoogleAuthProvider();
  provider.setCustomParameters({prompt: 'select_account'});
  const scopes = ['profile', 'email'];
  scopes.forEach(scope => provider.addScope(scope));
  try {
    return await firebase.auth().signInWithPopup(provider);
  } catch (error) {
    let message = '';
    switch (error.code) {
      case 'auth/account-exists-with-different-credential':
        message = 'Account exists with another sign in type';
        break;
      case 'auth/popup-closed-by-user':
        message = 'Login popup closed';
        break;
      default:
        message = 'Error signing in';
        break;
    }
    throw new Error(message);
  }
};

export const isLoggedIn = (): boolean => {
  const {currentUser} = firebase.auth();
  return currentUser !== null;
};

export const getUserDoc = (
  id: string
): firebase.firestore.DocumentReference => {
  return firebase
    .firestore()
    .collection(FIREBASE_COLLECTIONS.USERS)
    .doc(id);
};

export default firebase;

我从firebase实用程序调用getUserDoc函数,并使用它向用户写入数据。

function* registerWithPassword(user: UserInput) {
  try {
    const userData: firebase.auth.UserCredential = yield call(
      registerUser,
      user.email,
      user.password
    );
    if (userData === null || userData.user === null) {
      yield put(
        authFailureAction.failure({
          register: 'Unable to register user',
        })
      );
    } else {
      const userDoc = getUserDoc(userData.user.uid);   
      yield call(
        userDoc.set,
        {labels: [], pinnedNotes: [], name: user.name},
        {merge: true}
      );
    }
  } catch (e) {
    console.log({e});
    yield put(
      authFailureAction.failure({
        register: e.message || 'Unable to register user',
      })
    );
  }
}

userDoc.set被调用时,错误发生了。从一些调试中,它看起来像是firebase为空。这就是为什么firebase.firestore()抛出错误。但是如果firebase为空,auth应该也不工作,但我没有遇到任何firebase auth的问题。
还要注意的是,我在index.js文件中导入firebaseConfig.js,所以我确信firebase已经初始化了,这也是因为用户正在注册,但由于某种原因,当我从firebase.firestore()访问firestore时,firebase为空。
您可以访问项目here。尝试注册一个用户,您将看到错误。由于它依赖于Firebase,您必须添加一个相关的.env文件。

30byixjq

30byixjq1#

您必须使用已初始化的firebase。

import firebase from 'firebase/app'; <-- This one hasn't been initialized.
...
firebase.initializeApp(firebaseConfig);
export default firebase; <-- This one is initialized.

在firebase_config中,添加firestore和auth

import firebase from 'firebase/app';
import 'firebase/auth';      <----- add this here.
import 'firebase/firestore'; <----- add this here.

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

if (firebase.apps.length === 0) {
  console.log('Initializing firebase');
  firebase.initializeApp(config);
}

export default firebase;

更改前3行。

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

import {FIREBASE_COLLECTIONS} from './constants';

export const getIdToken = async () => {
  try {
    const {currentUser} = firebase.auth();
    if (currentUser) {
      const idToken = await currentUser.getIdToken();
....

import firebase from './firebase_config.js'; // or wherever your firebase.initializeApp(...) live.

import {FIREBASE_COLLECTIONS} from './constants';

export const getIdToken = async () => {
  try {
    const {currentUser} = firebase.auth();
    if (currentUser) {
      const idToken = await currentUser.getIdToken();
....

再见。

dgsult0t

dgsult0t2#

发生该错误的原因可能是在文件中完成多个firebase导入/导出,而不是将单个模块作为源。
firebase模块只能导出到firebase_config文件中,然后从那里导入到其他文件中。
因此在firebase_utils中,您可以添加以下内容而不是:

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

import firebase from './firebase-config.js';
您还可以从firebase_utils中删除export default firebase;,以防止firebase命名空间被覆盖。
因此,最终的firebase_config.js文件可能如下所示:

// Firebase App (the core Firebase SDK)
var firebase = require("firebase/app");

// Add the Firebase products that you want to use
require("firebase/auth");
require("firebase/firestore");

// Your app's Firebase project configuration
var firebaseConfig = {
  // ...
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

// Single source for all imports of the firebase module
export default firebase;

您还可以参考本文和this GitHub repo,以获得firebase导入示例。

相关问题