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

Firebase实时数据库权限拒绝:规则模拟器通过但代码报错

问题与解决方案

问题详情

Firebase实时数据库结构:users节点下以用户UID为键,每个键对应email、name两个字段。数据库规则如下:

{
  "rules": {
     "users": {
       "$uid": { 
         "email": {
           ".read": "auth.uid == $uid",
           ".write": "auth.uid == $uid"
        },
         "name": {
           ".read": "auth.uid == $uid",
           ".write": "auth.uid == $uid"
        }
      }
    }
  }
}

使用pyrebase执行写入操作时触发权限拒绝错误,但用户可正常登录,规则模拟器模拟请求却成功:

# 核心写入代码
db.child("users").child(self.user["localId"]).set({"name": name, "email" : email})

可复现问题的完整代码:

import pyrebase

config = {
    "apiKey": "",
    "authDomain": "",
    "projectId": "",
    "databaseURL": "",
    "storageBucket": "",
    "messagingSenderId": "",
    "appId": "",
    "measurementId": "",
}
firebase = pyrebase.initialize_app(config)
user = firebase.auth().sign_in_with_email_and_password("test@gmail.com", "password")
db = firebase.database()
# 此处token参数传错导致权限问题
db.child("users").child(user["localId"]).set({"name": "test", "email": "test@gmail.com"}, token=user["localId"])

问题原因

  1. Token参数错误:pyrebase的数据库操作需要传入用户的身份验证token(idToken),而非用户UID(localId)。传入localId无法完成身份校验,数据库判定为未授权请求。
  2. 规则权限覆盖问题:当前规则仅对email、name字段设置了读写权限,但set操作是对$uid节点进行整体写入/创建,Firebase会优先检查$uid节点的写权限——规则中未设置该节点的写权限,默认拒绝操作。规则模拟器若仅模拟单个字段的写入,会匹配到字段级权限而成功,但实际代码的set操作触发的是节点级权限校验。

解决方案

1. 修正代码中的Token参数

将token=user["localId"]替换为token=user["idToken"],确保数据库能识别用户身份:

db.child("users").child(user["localId"]).set({"name": "test", "email": "test@gmail.com"}, token=user["idToken"])

2. 调整数据库规则

推荐采用以下规则结构,将读写权限提升至$uid节点,同时保留字段级的格式校验,既支持set操作创建节点,又保证数据安全:

{
  "rules": {
     "users": {
       "$uid": { 
         ".read": "auth.uid == $uid",
         ".write": "auth.uid == $uid",
         "email": {
           ".validate": "newData.isString() && newData.val().matches(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/)"
        },
         "name": {
           ".validate": "newData.isString() && newData.val().length > 0"
        }
      }
    }
  }
}

若需严格限制仅允许创建节点(不允许覆盖整个节点),可采用如下规则:

{
  "rules": {
     "users": {
       "$uid": { 
         ".write": "auth.uid == $uid && !data.exists()",
         "email": {
           ".read": "auth.uid == $uid",
           ".write": "auth.uid == $uid"
        },
         "name": {
           ".read": "auth.uid == $uid",
           ".write": "auth.uid == $uid"
        }
      }
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:02:50