更新()调用

时间:2016-03-23 14:24:39

标签: firebase

Firebase.update()对于原子更新多个节点非常有用。但是,它似乎有限,因为安全规则仍由update()操作中的根节点定义。

例如,我们假设我的数据结构为:

users : {
    uid : {account: accountId, ...},
    ...
},
accounts : {
    accountId : {uid: uid, ....},
    ...
},
customers : {
    customerId : {uid: uid, accountId: accountId...},
    ...
}

我的Firebase安全性组织为:

{
    "rules": {
        "users" : {
            "$uid" : {
                ".read": "data.child('account').val() === root.child('users').child(auth.uid).child('account').val()",
                ".write": "data.child('account').val() === root.child('users').child(auth.uid).child('account').val()" 
              }
        },
        "accounts" : {
              "$accountId” : {
                    ".read": "data.child('users').child(auth.uid).exists() || newData.child('users').child(auth.uid).exists()",
                    ".write": "data.child('users').child(auth.uid).exists() || newData.child('users').child(auth.uid).exists()"
              }
        },
        “customers” : {
              "$customerId” : {
                  ".read": "root.child('users').child(auth.uid).child('account').val() == root.child('customers').child($customerId).child('account').val()",
                  ".write": "root.child('users').child(auth.uid).child('account').val() == root.child('customers').child($customerId).child('account').val()" 
                }
        }
   }

要跨这些节点对给定的businessId进行原子更新,我可以进行update()调用:

firebaseRef.update({
    accounts : {
        accountId : { foo: bar },
    },
    customers : {
        customerId : { foo: bar },
    }
}

由于update()应仅修改指定的位置,因此可以应用逐节点安全规则(例如,使用uid)。但是,似乎根安全性(例如/)占优势,我收到了警告:

FIREBASE WARNING: update at / failed: permission_denied 

所以现在我使用promise链来使用set()按顺序更新不同的节点,这意味着我将失去原子操作。

是否有更好的方法可以跨多个节点进行原子操作而无需打开root的安全性?

2 个答案:

答案 0 :(得分:0)

在您的安全规则中,root指的是根目录中的当前/旧数据。如果要在根目录中访问新数据,则必须从newData

导航到该数据
".read": "newData.parent().parent().child('businessDta')...

我们的Bolt语言有一个特殊的快捷方式,当您使用root时,它实际上会为您生成必要的newData.parent().parent()...来电。

答案 1 :(得分:0)

我遇到过这个问题,我通过修复更新中每个路径的安全规则来解决这个问题。事实证明SDK适用于update()和安全规则。

对于您的情况,您可能需要仔细检查/accounts/accountId/customers/customerId的安全规则是否适用于您的update()电话。您可以通过将更新分成原始set()调用来调试此操作,以测试每个更新路径是否正在使用规则。

但是,我认为您可能在“/ accounts / $ accountId”规则中输入错字。您可能需要root.child("users")代替data.child("users")