我尝试在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
文件。
2条答案
按热度按时间30byixjq1#
您必须使用已初始化的firebase。
在firebase_config中,添加firestore和auth
更改前3行。
到
再见。
dgsult0t2#
发生该错误的原因可能是在文件中完成多个firebase导入/导出,而不是将单个模块作为源。
firebase
模块只能导出到firebase_config
文件中,然后从那里导入到其他文件中。因此在
firebase_utils
中,您可以添加以下内容而不是:import firebase from './firebase-config.js';
您还可以从
firebase_utils
中删除export default firebase;
,以防止firebase
命名空间被覆盖。因此,最终的
firebase_config.js
文件可能如下所示:您还可以参考本文和this GitHub repo,以获得
firebase
导入示例。