Cloud Firestore安全规则问题:如何限制用户仅访问自身文档?
问题根源与解决方案
核心问题:前端查询与安全规则不匹配
你遇到的权限错误,本质是前端请求的范围和安全规则允许的范围不一致:
- 你的安全规则只允许用户访问自己的单个文档(通过UID/邮箱匹配文档ID)
- 但前端代码是查询整个
users集合,Firestore会拒绝这种请求——因为规则要求查询结果里的所有文档都必须符合权限,而你显然没有权限访问其他用户的文档,所以整个请求被拦截。
另外先纠正几个早期规则的错误:
- 第一个失效规则里的
database == "users"完全错误:{database}变量对应的是Firestore数据库的名称(默认是(default)),不是集合名,这个条件永远不成立。 - 第二个早期失效规则缺少根路径匹配:Firestore规则必须从
/databases/{database}/documents开始定义,否则不会匹配任何文档路径。
解决方案:分两种场景配置(根据你的文档ID类型)
场景1:文档ID = Firebase Auth用户UID(推荐方案)
这是Firestore用户数据存储的标准做法,UID是用户的唯一、不可变标识。
安全规则配置
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 仅允许用户访问自己的文档(文档ID = 用户UID) match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; } } }
前端代码修改
不要查询整个集合,直接获取当前登录用户的单个文档:
async getUserData ({ commit }) { // 先获取当前登录用户 const user = auth.currentUser; if (!user) { console.log('用户未登录'); return; } // 直接获取当前用户的文档(文档ID = 用户UID) const docRef = doc(db, 'users', user.uid); const docSnap = await getDoc(docRef); if (docSnap.exists()) { console.log(`${docSnap.id} => ${JSON.stringify(docSnap.data())}`); // 提交到Vuex commit('SET_USER_DATA', docSnap.data()); } else { console.log('用户文档不存在'); } }
场景2:文档ID = 用户邮箱(你的当前数据结构)
如果你的users集合文档ID是用户邮箱(比如dave@domain.co.uk),按以下配置:
安全规则配置
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{email} { allow read, write: if request.auth != null && request.auth.token.email == email; } } }
前端代码修改
同样直接获取单个文档,而不是查询整个集合:
async getUserData ({ commit }) { const user = auth.currentUser; if (!user) { console.log('用户未登录'); return; } // 文档ID = 用户邮箱 const docRef = doc(db, 'users', user.email); const docSnap = await getDoc(docRef); if (docSnap.exists()) { console.log(`${docSnap.id} => ${JSON.stringify(docSnap.data())}`); commit('SET_USER_DATA', docSnap.data()); } else { console.log('用户文档不存在'); } }
关键注意事项
- 永远不要查询整个用户集合:除非你真的需要获取所有用户数据(且有权限),单个用户数据用
getDoc获取单个文档更高效,也符合安全规则的要求。 - Rules Playground使用技巧:测试时要选择“获取文档”(而非“获取集合”),并在模拟认证信息里填写正确的UID或邮箱,才能匹配规则通过验证。
内容的提问来源于stack exchange,提问作者Dave Chambers
相关产品推荐
相关产品推荐

