如何编写Firebase Realtime Database列表规则解决分组查询权限报错
报错原因
Firebase 实时数据库安全规则存在语法限制:query.orderByChild 做相等比较时,右侧操作数必须是静态字符串字面量,你原有规则中'users/' + auth.uid是运行时动态拼接的字符串,不符合规则要求,所以触发报错。
解决方案
方案1:调整数据结构(官方推荐最佳实践)
你当前的组内嵌套用户的结构,更适合查询单组下的所有授权用户,不适合查询单用户所属的所有组,还会遇到索引无法通用配置、规则难写的问题。推荐新增userGroups节点单独存储用户和组的映射关系:
{ // 保留原有users、groups节点不变 "userGroups": { "userA": { "groupA": true }, "userC": { "groupA": true } } }
修改查询代码直接取当前用户的组列表即可:
const user = firebase.auth().currentUser firebase .database() .ref(`/userGroups/${user.uid}`) .once('value', (v) => { // 返回的所有key就是用户有权限的组ID console.log(Object.keys(v.val() || {})) });
对应安全规则配置:
{ "rules": { "userGroups": { "$uid": { ".read": "$uid === auth.uid" } }, "groups": { "$groupId": { ".read": "data.child('users/' + auth.uid).val() === true" } } } }
后续更新组的授权用户列表时,同步更新userGroups节点的对应数据即可,该方案查询效率更高,规则配置更简单。
方案2:不调整原有数据结构的规则配置
如果你不想修改现有数据结构,可以通过正则匹配+字符串替换的方式绕过静态字面量限制,同时配置通用索引:
{ "rules":{ "groups": { ".indexOn": ["users"], ".read": "query.orderByChild.matches(/^users\\/.+$/) && query.orderByChild.replace('users/', '') === auth.uid && query.equalTo === true" } } }
该规则先校验排序路径符合users/xxx的格式,再提取路径中的用户ID和当前登录用户ID对比,同时校验查询值为true,完全符合你原来的查询逻辑。
内容的提问来源于stack exchange,提问作者Simon Tran
相关产品推荐
相关产品推荐

