Firebase Realtime Database规则失效:用户无法读写匹配UID的文档
问题排查:Firebase实时数据库用户权限被拒绝
我有一个名为Users的节点,里面的文档使用自动生成的推送ID作为键,每个文档都包含存储用户Auth.UID值的UID字段。我写了安全规则,想让用户只能读写UID字段和自己auth.uid匹配的文档,但现在所有权限都被拒绝,帮忙排查问题。
实时数据库结构
{ "Users": { "-MTvNT3Cw7JAKaMbfFuv": { "Email": "*****@gmail.com", "UID": "9Sv14dBARRTS9jsbE3j1uh0XytA2" }, "-MTxOpssHRPWUCk474CZ": { "Email": "*****@gmail.com", "UID": "FAcKFSDuGOg7TdqZaInk9PDIlou1" } } }
当前安全规则
{ "rules": { "Users": { "$userDocId": { ".read": "auth !== null && data.child('UID').val() === auth.uid", ".write": "auth !== null && data.child('UID').val() === auth.uid" } } } }
规则测试日志
Line 5 (/Users/MTvNT3Cw7JAKaMbfFuv) read: "auth !== null && data.child('UID').val() === auth.uid"
问题原因及修复方案
1. 规则语法错误:使用了HTML转义字符
当前规则中的&&是HTML转义后的逻辑与运算符,Firebase规则无法识别,必须替换为原生的&&,否则规则会直接失效,拒绝所有请求。
2. 写入规则未覆盖文档创建场景
当创建新用户文档时,data代表修改前的数据(此时为空),data.child('UID').val()不存在,导致写入规则不通过。需要区分创建新文档和更新已有文档两种场景:
- 创建文档:检查新文档的
UID字段值等于当前用户的auth.uid - 更新文档:既要确保原文档的
UID属于当前用户,也要防止用户修改UID字段
修复后的安全规则
{ "rules": { "Users": { "$userDocId": { ".read": "auth !== null && data.child('UID').val() === auth.uid", ".write": "auth !== null && newData.child('UID').val() === auth.uid && (data.exists() ? data.child('UID').val() === auth.uid : true)" } } } }
测试注意事项
- 读取操作需针对单个用户文档路径(如
/Users/-MTvNT3Cw7JAKaMbfFuv),读取整个/Users节点会被拒绝(符合预期,用户不应访问他人数据)。 - 创建新文档时,必须携带
UID字段且值与当前用户auth.uid完全一致;更新文档时,不能修改UID字段值。
内容的提问来源于stack exchange,提问作者Aly
相关产品推荐
相关产品推荐

