Firebase实时数据库规则如何比对请求用户UID与管理员UID
问题原因
你的规则有两个核心错误:
- 比对逻辑用错了变量:
$user_id是路径通配符匹配到的URL片段值,和当前登录用户身份没有任何关系。Firebase规则里要拿发起请求的已登录用户UID,必须用内置全局变量auth.uid。 - 规则层级逻辑错误:Firebase实时数据库的
.read/.write权限是自上而下生效的——某一层开了权限,下面所有子节点默认继承这个权限,子节点没法收回上层开的权限;反过来如果上层没开权限,子节点配的规则只管自己和自己下面的路径,根本管不到上层的操作。你现在把.write规则写在/Calender/$user_id这层,只要你set的路径不是精确匹配/Calender/[你写死的管理员UID],都会被直接拒绝。
正确配置方案
方案1:硬编码固定管理员UID(适合管理员数量少、不会频繁变动的场景)
直接在需要控制权限的路径层,用auth.uid和管理员UID做精确比对即可:
{ "rules": { "Calender": { ".read": true, // 直接在Calender节点层配置写权限,覆盖该节点下所有子路径的写操作 ".write": "auth.uid === '从Firebase控制台复制的管理员完整UID,注意不要带多余空格'", "$user_id": { // 如有需要可在这里追加数据格式校验规则,或给普通用户开放自身路径的权限 } } } }
方案2:动态管理员列表(适合管理员需要动态增减的场景)
先在数据库中单独维护管理员列表节点,存储结构为/admins/[管理员UID] = true,再在规则中通过查询根节点数据判断当前用户是否在管理员列表中:
{ "rules": { "admins": { ".read": false, ".write": false, // 禁止前端直接修改管理员列表,仅通过控制台或服务端Admin SDK维护 "$admin_id": { ".validate": "newData.isBoolean() && newData.val() === true" } }, "Calender": { ".read": true, // 判断当前登录用户是否存在于管理员列表中 ".write": "auth != null && root.child('admins').child(auth.uid).exists()", "$user_id": { // 其他自定义规则 } } } }
排查注意点
- 规则修改发布后最多需要2分钟完成全量同步,刚发布后立即测试可能命中旧规则缓存
- 测试前可以在客户端打印当前登录实例的
auth.currentUser.uid,确认和规则中配置的UID完全一致,多余空格、字符缺漏都会导致比对失败 - 如果你的set操作是直接写入
/Calender根节点而非/Calender/[具体子ID]路径,必须在Calender层级配置.write规则,下层的规则不会对上层路径生效
内容的提问来源于stack exchange,提问作者Jacob Klaren
相关产品推荐
相关产品推荐

