Firebase权限不足错误:React社交登录后无法读取Firestore用户文档
问题描述
我在开发React应用时,通过Firebase Auth实现Google/Facebook第三方登录,登录后需要检查Firestore的users集合中是否存在当前用户的文档,若不存在则创建该文档。但执行docRef.get()调用时触发权限错误:
Uncaught (in promise) FirebaseError: Missing or insufficient permissions.
相关业务代码:
function loginSocial(provider) { return auth.signInWithPopup(provider).then((res) => { // 登录成功后检查数据库中是否存在用户文档 console.log(user.uid, auth.currentUser.uid); var docRef = app.firestore().collection('users', res.user.uid) docRef.get().then((doc) => { if (doc.exists) { // 文档存在则不做操作 } else { // 创建用户文档的代码 }
当前Firestore安全规则:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { // 允许用户读取/更新自己的文档 allow read, update: if request.auth != null && request.auth.uid == userId; } // 允许用户操作自己文档下的嵌套集合 match /users/{userId}/{document=**} { allow read, write: if request.auth != null && request.auth.uid == userId; } } }
问题原因
文档引用错误
你使用collection('users', res.user.uid)的方式是错误的,collection()方法仅接受集合名称作为参数,这段代码实际创建的是整个users集合的引用,而非该集合下特定用户的文档引用。当调用docRef.get()时,你在尝试读取整个users集合的所有文档,但安全规则仅允许用户读取自己的单个文档,因此触发权限不足错误。安全规则缺少创建权限
当前规则仅赋予了read和update权限,没有包含create操作权限,即便修正了文档引用,后续创建用户文档时也会因权限不足失败。
解决方法
1. 修正文档引用代码
将获取文档引用的代码改为正确的写法:先获取users集合,再通过doc()方法指定用户ID:
// 错误写法 // var docRef = app.firestore().collection('users', res.user.uid) // 正确写法 var docRef = app.firestore().collection('users').doc(res.user.uid);
2. 更新Firestore安全规则
为用户文档添加create权限,确保规则覆盖所需操作:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { // 允许用户读取、更新、创建自己的文档 allow read, update, create: if request.auth != null && request.auth.uid == userId; } // 允许用户读写自己文档下的嵌套集合 match /users/{userId}/{document=**} { allow read, write: if request.auth != null && request.auth.uid == userId; } } }
3. 完善用户文档创建逻辑
在else分支中添加正确的文档创建代码,示例如下:
else { // 创建用户文档,可根据需求存储用户信息 docRef.set({ uid: res.user.uid, email: res.user.email, displayName: res.user.displayName, createdAt: firebase.firestore.FieldValue.serverTimestamp() }) .then(() => { console.log("用户文档创建成功"); }) .catch((error) => { console.error("创建文档失败:", error); }); }
内容的提问来源于stack exchange,提问作者Brian HK
相关产品推荐
相关产品推荐

