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

如何在Firebase实时数据库规则中实现跨UID读取店铺状态

Firebase实时数据库规则调整方案:实现客户读取关联店铺营业状态

需求背景

我开发了一款客户应用,需要实现两个核心需求:

  • 客户用户能够获取其关联店铺的营业状态(setShopOnOff字段)
  • 店铺主人能够修改自己店铺的setShopOnOff字段值

当前Firebase实时数据库规则仅允许用户读取自身UID对应的数据,无法实现跨UID的关联读取。以下是现有数据结构、规则及前端请求代码,需调整规则满足需求。

现有数据结构

users
  SHOPID--rOOXXXoyCggX2
    distributorId:"ASSSSASPbkHX2"
    email:"fSSASA@g.com"
    setShopOnOff:true
  CUSTOMERUID--fXXX5EjEVksOr53
    acquired:true
    customer:true
    email : "csddd@g.com"
    franchiseId : "SHOPID--rOOXXXoyCggX2"
    income
    myAccount

当前数据库规则

{
  "rules": {
    "users": {  
      "$uid": {
        "setShopOnOff": { 
            ".read": "auth != null && auth.uid == $uid", 
            ".write": "$uid === auth.uid"
        },
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    },
    "orders": {
        "$uid": {
          ".read": "$uid === auth.uid",
          ".write": "$uid === auth.uid"
        }
    }
  }
}

前端请求代码

const userdata = ref(db, `/users/${user1.uid}`);
await onValue(userdata, (snapshot) => {
  grabbedData.push(snapshot.val());
 
  setShowloading(false);
  if (grabbedData) {
    Object.keys(grabbedData).map(function (key) {
      let x = grabbedData[key];
      if (x) {
        if (x.customer) {
          setCustomer(true);
          franchiseId1 = x.franchiseId;
          if (x.myAccount) {
            ShopName = x.myAccount.shopName;
            cityName = x.myAccount.city;
            setShopName(ShopName);
            setCity(cityName);

            if (franchiseId1) {
              const getFranchiseIdData = ref(db, `/users/${franchiseId1}`);
              onValue(getFranchiseIdData, (snapshot1) => {
                franchiseIddata.push(snapshot1.val());
                console.log(snapshot1.val());
                setIsShopOpen(franchiseIddata[0].setShopOnOff);
              });
            }
          }
        } else {
          setCustomer(false);
        }
      }
    });
  }
});

规则调整方案

核心思路

  1. 针对店铺的setShopOnOff字段:
    • 允许店铺主人(UID与店铺节点ID一致)读写该字段
    • 允许关联客户(自身节点franchiseId等于店铺节点ID)读取该字段
  2. 用户其他私有数据(如邮箱、income等)仍保持仅本人可读写的权限

调整后的规则代码

{
  "rules": {
    "users": {  
      "$uid": {
        // 其他私有字段保持仅本人可读写
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid",
        // 单独配置setShopOnOff的权限
        "setShopOnOff": {
          ".read": "auth != null && ($uid === auth.uid || root.child('users').child(auth.uid).child('franchiseId').val() === $uid)",
          ".write": "$uid === auth.uid"
        }
      }
    },
    "orders": {
        "$uid": {
          ".read": "$uid === auth.uid",
          ".write": "$uid === auth.uid"
        }
    }
  }
}

规则说明

  • .read规则新增的root.child('users').child(auth.uid).child('franchiseId').val() === $uid:验证当前登录用户的franchiseId是否与目标店铺的节点ID($uid)匹配,匹配则允许读取该字段。
  • .write规则保持不变,仅店铺主人拥有修改权限。

前端代码优化建议

当前请求的是整个店铺节点,可改为仅请求setShopOnOff字段,减少不必要的数据传输,同时更贴合权限规则设计:

// 替换原请求整个店铺节点的代码
if (franchiseId1) {
  const shopStatusRef = ref(db, `/users/${franchiseId1}/setShopOnOff`);
  onValue(shopStatusRef, (snapshot1) => {
    const isOpen = snapshot1.val();
    setIsShopOpen(isOpen);
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:18:27