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

Firebase Realtime DB如何配置规则避免写入已存在的ExponentPushToken

原有规则失效原因

  • 路径匹配错误:你的规则定义在根节点下,data.child('push_token')取的是根目录的push_token节点,而实际你的push_token在users节点下,路径不匹配导致校验逻辑完全取错了值。
  • 对比逻辑错误:data.child('push_token').val()返回的是整个push_token节点的对象(包含所有自动生成key和对应token的键值对),和你新写入的单个token字符串对比永远不相等,校验自然不生效。
  • 未适配push操作特性:每次调用push()会生成随机新key,写入路径是users/push_token/[新随机key],原有规则没有遍历所有已存token做判断,拦不住重复写入。

推荐解决方案(改存储结构,性能最优)

直接用ExponentPushToken作为节点key,利用Firebase节点key天然唯一的特性实现去重,规则实现最简单,性能最高。

调整后存储结构

{
  "users" : {
    "push_tokens" : {
      "转义后的ExponentPushToken值" : true
    }
  }
}

注:ExponentPushToken自带的[、]字符可以在前端写入前替换为下划线等合法字符,避免路径解析异常

对应规则配置

{
  "rules": {
    ".read": "false",
    "users": {
      "push_tokens": {
        "$token": {
          // 仅当该token对应的节点不存在时允许写入
          ".write": "!data.exists()"
        }
      }
    }
  }
}

前端写入时不要用push()方法,直接调用set()写入到users/push_tokens/[转义后的token]路径,值设为true即可,已存在的token会被规则直接拦截写入


兼容现有存储结构的解决方案

如果不想调整现有存储结构,继续使用自动生成key的模式,可以用以下规则:

{
  "rules": {
    ".read": "false",
    "users": {
      "push_token": {
        "$autoKey": {
          // 校验新写入的token在所有已存token中不存在
          ".write": "data.parent().children().filter(child => child.val() === newData.val()).length === 0"
        }
      }
    }
  }
}

注:该方案需要遍历所有已存token做判断,当push_token下数据量较大时写入性能会明显下降,仅推荐数据量较小的场景使用


内容的提问来源于stack exchange,提问作者Mark-The-Guitar-Guy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:48:02