Firebase Realtime Database规则配置问题:用户无法读写自有分类
问题分析与解决
你的规则配置和实际数据结构不匹配,这是触发权限错误的核心原因:
规则配置的问题
当前规则中,categories节点下直接以$uid作为子节点路径,要求用户只能读写categories/自己的uid路径下的数据。但实际你的数据结构是categories下是数字索引节点,每个节点内部包含uid字段,规则的路径匹配逻辑完全不贴合实际存储结构,自然会触发权限拒绝。
修正后的规则配置
需要调整规则,针对categories下的每个分类节点(用$categoryId表示任意分类ID),校验该节点内的uid字段是否与当前认证用户的uid一致:
{ "rules": { "users": { "$uid": { ".write": "auth != null && $uid === auth.uid", ".read": "auth != null && $uid === auth.uid" } }, "categories": { "$categoryId": { ".write": "auth != null && newData.child('uid').val() === auth.uid", ".read": "auth != null && data.child('uid').val() === auth.uid" }, // 支持批量查询自己的分类:需配合orderByChild('uid')的查询条件使用 ".read": "auth != null && query.orderByChild('uid').equalTo(auth.uid)" } } }
- 写入规则:确保新写入的分类数据中
uid字段等于当前用户的auth.uid,防止用户篡改不属于自己的分类。 - 读取规则:单个分类读取时校验其
uid字段;批量读取时,限制只能查询与自己uid匹配的分类。
代码优化建议
你当前通过data.children.length生成分类ID的方式存在并发问题(多个用户同时写入时可能生成重复ID),建议改用Firebase的push()方法自动生成唯一ID:
String uId = await userId(); final databaseRef = FirebaseDatabase.instance.ref('categories'); // 使用push()生成唯一节点ID var newCategoryRef = databaseRef.push(); await newCategoryRef.set(<String, dynamic>{ "name": categoryBody.name, "description": categoryBody.description, "uid": uId, "id": newCategoryRef.key // 用push生成的key作为分类ID });
内容的提问来源于stack exchange,提问作者rjkolli7
相关产品推荐
相关产品推荐

