Firebase Cloud Firestore角色鉴权规则允许get但禁止list问题排查
问题核心原因
你遇到的查询失败问题来自安全规则逻辑冗余+Firestore列表查询的规则校验限制:
- 单文档
get请求时,规则可以直接获取目标文档的完整数据,执行你写的get()校验逻辑,因此可以正常通过 - 集合
list查询时,规则引擎需要提前验证所有可能符合查询条件的文档都满足权限要求,你在权限判断函数中调用了get()方法,规则引擎无法为所有潜在匹配的文档预先执行这个调用做校验,因此直接拒绝了查询 - 额外的逻辑冗余:你对
organizations集合的权限判断完全不需要调用get(),当前要访问的就是organization文档本身,它的users数组可以直接从resource.data读取,不需要再调用接口拉取当前文档本身,这是导致查询失败的直接诱因。
修正后的安全规则
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { function isSignedIn() { return request.auth != null; } // 校验用户是否属于当前访问的组织文档 function userBelongsToCurrentOrg() { return isSignedIn() && request.auth.uid in resource.data.users; } // 校验用户是否属于event关联的组织 function userBelongsToEventOrg() { return isSignedIn() && request.auth.uid in get(/databases/$(database)/documents/organizations/$(resource.data.orgid)).data.users; } match /organizations/{org} { allow read: if userBelongsToCurrentOrg(); allow write: if false; } match /events/{event} { allow read: if userBelongsToEventOrg(); allow write: if userBelongsToEventOrg(); } } }
后续使用注意
如果你后续需要查询events集合的列表,需要保证查询带上orgid过滤条件,让规则引擎可以确定你查询的所有event都属于同一个你有权限的组织,否则依然会触发权限拒绝,示例查询写法:
// 先获取当前用户所属的组织orgid,再过滤查询对应events firebase.firestore().collection('events').where('orgid', '==', 'devtest')
你现有的organizations集合查询写法where('users', 'array-contains', 当前用户uid)已经和修正后的规则匹配,更新规则后即可正常返回结果。
内容的提问来源于stack exchange,提问作者Dylan Smith
相关产品推荐
相关产品推荐

