Firestore安全规则写入正常但查询Runsheets集合数据被拒
Firestore 安全规则查询报权限错误但写入正常排查方案
问题核心原因
- Firestore安全规则不是数据过滤器:当你对集合发起列表查询(即代码中通过
getDocs查询Runsheets集合的操作)时,Firestore不会拉取全量文档再逐个校验权限,只会直接校验你的查询条件是否能100%保证返回结果全部符合权限要求,校验不通过会直接拒绝请求,哪怕你实际要查的文档本身符合权限也会报错。 - 你原有规则中
allow read的判断逻辑仅对单文档操作(单文档读取、写入、更新、删除)生效:写入操作是单文档级别的create请求,规则可以直接校验待写入文档的RunsheetID字段和登录用户uid一致,所以可以正常执行;但集合查询属于list操作,原有规则没有配置和查询条件匹配的校验逻辑,所以直接拦截。
修复步骤
1. 更新安全规则
将原有规则替换为以下内容,拆分读权限为单文档读和集合列表查询两类,分别配置校验逻辑:
service cloud.firestore { match /databases/{database}/documents { match /Runsheets/{RunsheetID} { // 单文档读取、更新、删除:校验文档所属用户和当前登录用户一致 allow get, update, delete: if isAuthenticated() && request.auth.uid == resource.data.RunsheetID; // 集合列表查询:必须携带RunsheetID等于当前登录用户uid的等值查询条件,才允许执行 allow list: if isAuthenticated() && request.auth.uid == request.query.where.RunsheetID.`==`; // 新建文档逻辑保持原有校验 allow create : if isAuthenticated() && request.auth.uid == request.resource.data.RunsheetID; } } } function isAuthenticated() { return request.auth != null ; }
2. 部署规则后验证
你现有查询代码已经携带了where("RunsheetID", "==", User.uid)的过滤条件,和规则中对list查询的约束完全匹配,部署新规则后即可正常拉取数据。
优化建议:如果每个用户仅对应一条Runsheet记录,可以在写入时直接将用户uid作为文档ID存储,使用
setDoc(doc(db, "Runsheets", User.uid), {starttime: ...})替代addDoc自动生成ID的写法,对应规则可以简化为allow read, write: if isAuthenticated() && request.auth.uid == RunsheetID,性能更好也更不容易出现规则匹配问题。
内容的提问来源于stack exchange,提问作者Blnk
相关产品推荐
相关产品推荐

