Firebase查询公开数据时遭遇权限拒绝问题求助
问题分析与解决方案
你的问题核心在于Firebase安全规则的作用层级错误,导致查询请求被直接拒绝,而非返回空结果。
原规则的问题
当前的.read规则定义在shaders节点上,Firebase会先校验整个shaders节点的读取权限,而非逐个校验子节点:
- 当未登录用户尝试读取
userShaders/${uid}/shaders时,规则会检查shaders节点本身是否满足auth.uid === $uid || data.child('public').val() == true。 - 但
shaders节点本身没有public属性,data.child('public').val()返回null,同时你也不是该用户,因此整个节点的读取权限被直接拒绝,不会触发后续的查询过滤。
修改后的安全规则
需要将权限校验下移到单个shader节点,并添加查询规则限制请求条件:
{ "rules": { "userShaders": { "$uid": { "shaders": { ".indexOn": "public", // 为public字段建立索引,提升查询效率 "$shaderId": { ".write": "auth.uid === $uid", // 单个shader节点的权限:所有者可读写,公开节点允许所有人读 ".read": "auth.uid === $uid || data.child('public').val() == true" }, // 限制shaders节点的查询请求:仅允许按public=true过滤的查询 ".read": "query.orderByChild == 'public' && query.equalTo == true" } } } } }
规则说明
- 单个shader节点权限:确保只有所有者能修改,公开的shader允许所有用户读取。
- shaders节点查询规则:强制要求查询必须是
orderByChild("public").equalTo(true),Firebase会先校验查询条件符合规则,再返回所有符合单个节点.read权限的子数据。 - 索引配置:添加
.indexOn避免查询性能问题,Firebase会自动为public字段建立索引。
效果验证
修改规则后,你原有的查询代码无需改动:
val shaderRef = db .getReference("userShaders/${uid}/shaders") .orderByChild("public") .equalTo(true); shaderRef.get().addOnSuccessListener { // 无公开数据时返回空Snapshot,不会触发权限错误 }
当目标用户没有公开shader时,请求会成功返回空结果;有公开shader时,只会返回符合条件的记录,非公开数据会被规则过滤。
内容的提问来源于stack exchange,提问作者max pleaner
相关产品推荐
相关产品推荐

