如何在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); } } }); } });
规则调整方案
核心思路
- 针对店铺的
setShopOnOff字段:- 允许店铺主人(UID与店铺节点ID一致)读写该字段
- 允许关联客户(自身节点
franchiseId等于店铺节点ID)读取该字段
- 用户其他私有数据(如邮箱、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
相关产品推荐
相关产品推荐

