You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调整Firebase实时数据库规则:普通用户无法创建数据的问题排查

问题

现有Firebase实时数据库规则在单用户场景下运行正常:

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null",
    "confirmations": {
      ".read": false,
      ".write": true
    }
  }
}

尝试添加权限更低的用户后,新增用户无法在数据库中创建新对象,修改后的规则如下:

{
  "rules": {
    ".read": "auth != null", // 所有已认证用户可读取
    ".write": "auth.uid === 'AdminUID' || (!data.exists() && newData.exists())",
    ".validate": "auth.uid === 'AdminUID' || (!data.exists() && newData.exists())"
  }
}

(已将AdminUID替换为实际UID,但问题仍存在:新增用户可读取但无法创建新数据,也无法修改现有数据)

期望权限:

  • 管理员:拥有读取、修改、删除、创建数据的全部权限
  • 普通用户:仅能读取和创建新条目,无法修改或删除现有数据
解决方案

问题出在规则的作用层级和逻辑判断上:

  1. 根节点的data.exists()判断不适用子节点创建:当普通用户尝试在根节点下创建子节点时,根节点本身是存在的,所以根节点规则中的!data.exists()会返回false,导致普通用户的写入条件不成立。
  2. 冗余的.validate规则:.validate用于验证数据格式,这里不需要重复写入权限的判断,反而可能干扰正常的写入逻辑。

正确的规则应该针对子节点层级设置权限,示例如下:

{
  "rules": {
    ".read": "auth != null", // 所有已认证用户可读
    ".write": "auth.uid === 'AdminUID'", // 管理员拥有根节点级别的全权限(包括删除根下所有数据)
    "$nodeId": { // 匹配所有子节点
      ".write": "auth.uid === 'AdminUID' || (!data.exists() && newData.exists())"
      // 管理员可修改/删除该子节点;普通用户仅能创建新子节点(该节点不存在时写入)
    },
    "confirmations": { // 保留原有的confirmations节点规则(如果需要)
      ".read": false,
      ".write": "auth != null" // 或根据需求调整权限范围
    }
  }
}

规则说明

  • 根节点的.write仅开放给管理员,防止普通用户误删整个根节点下的数据。
  • 通过$nodeId匹配所有子节点,针对单个子节点判断权限:
    • 管理员UID匹配时,拥有该子节点的全部写入权限(创建、修改、删除)。
    • !data.exists() && newData.exists()确保普通用户只能创建新的子节点,无法修改或删除已存在的节点。
  • 如果不需要保留confirmations节点的特殊规则,可以直接删除该部分。

内容的提问来源于stack exchange,提问作者Dominick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:02:34