Firebase实时数据库规则问题:字段级权限被主节点规则覆盖
Firebase 数据库规则问题修正
数据库结构
{ "UserData":{ "123456789":{ "Nickname":"bestUser", "RecieveUpdates":"YES", "Status":"157" } } }
注:示例中 uid = 123456789
需求规则
- 所有已认证用户可在
UserData下创建新用户记录; - 仅记录所有者(
auth.uid等于路径中的$uid)可删除该记录; - 仅记录所有者可编辑
Nickname、RecieveUpdates字段; - 所有已认证用户可编辑任意用户的
Status字段。
当前使用规则
{ "rules":{ "UserData":{ "$uid":{ ".read":"auth != null", ".write":"auth != null && (!newData.exists() && $uid == auth.uid) || (!data.exists() && newData.exists())", "Nickname":{ ".write":"$uid == auth.uid", ".validate":true }, "RecieveUpdates":{ ".write":"$uid == auth.uid", ".validate":true }, "Status":{ ".write":"auth != null", ".validate":true }, "$other":{ ".validate":false } } } } }
当前问题
创建和删除记录功能正常,但Nickname、RecieveUpdates字段可被任意已认证用户编辑。原因是主节点的.write规则覆盖了字段级规则:主节点允许所有已认证用户进行写入操作(包括更新已有记录),导致字段级的权限限制被绕过。
修正后的规则
{ "rules":{ "UserData":{ "$uid":{ ".read":"auth != null", // 主节点仅控制创建和删除权限,更新权限交给字段级规则 ".write": "auth != null && ( // 创建新记录:原数据不存在,新数据存在 (!data.exists() && newData.exists()) || // 删除记录:新数据不存在,且操作人是记录所有者 (!newData.exists() && $uid == auth.uid) )", "Nickname":{ // 仅所有者可写入(创建时初始化或后续更新) ".write": "$uid == auth.uid", ".validate": true }, "RecieveUpdates":{ ".write": "$uid == auth.uid", ".validate": true }, "Status":{ // 所有已认证用户可写入(创建或更新) ".write": "auth != null", ".validate": true }, "$other":{ ".validate": false } } } } }
规则说明
- 主节点权限拆分:将写入权限拆分为创建和删除两种场景,不再包含更新操作的权限,避免主节点放开所有写入权限导致字段级规则失效。
- 字段级权限控制:
Nickname和RecieveUpdates仅允许所有者写入,无论是创建记录时初始化字段,还是后续更新字段;Status允许所有已认证用户写入,满足任意用户修改状态的需求;
- 非法字段拦截:通过
$other规则禁止创建需求外的字段,保证数据结构合规。
内容的提问来源于stack exchange,提问作者nikitas
相关产品推荐
相关产品推荐

