2016-03-23 20 views
1

Firebase.update()は、複数のノードをアトミ​​ックに更新するのに非常に便利です。ただし、セキュリティルールがupdate()操作のルートノードによって依然として定義されているため、制限されているように見えます。私Firebaseセキュリティは次のように整理されupdate()呼び出しのための細かなFirebaseセキュリティ

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

:たとえば、のは、私のデータが構成されているとしましょう

これらのノード間で与えられたbusinessIdのためのアトミック更新を行うには

{ 
    "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()" 
       } 
     } 
    } 

、私はので

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

次のようなupdate()電話をかけることができますは、指定された場所のみを変更すべきであり、ノードごとのセキュリティルールを適用することができる。 uidを使用)。

FIREBASE WARNING: update at/failed: permission_denied 

だから今、私が代わりにIを意味しているset()を使用してシーケンス内の異なるノードを更新するために、約束のチェーンを使用しています:しかし、ルートセキュリティ(例えば/)が優勢で、私のような警告が出ているようです原子操作を失う。

ルートのセキュリティを開かなくても、複数のノードにわたってアトミック操作を行うより良い方法はありますか?

+1

上記の火災基地構造の規則を(テキストとして)掲載してください。 – Jay

+0

こんにちはジェイ!返事が遅くなってごめん。私のアプリケーションは少し複雑すぎて完全なセキュリティルールを投稿することができず、問題を再現する簡単な方法を考えることができませんでした。しかし、一般に、すべての更新されたサブノードがセキュリティを通過する場合、ルートノード上でupdate()呼び出しが機能する必要がありますか?もしそうなら、おそらく今私のために不正なセキュリティ設定になっているでしょう。 –

+0

問題を解決しましたか? – Ymmanuel

答えて

0

セキュリティルールでは、rootは、ルートの現在の/古いデータを参照します。あなたがルートに新しいデータにアクセスしたい場合は、newDataから、それに移動する必要があります。

".read": "newData.parent().parent().child('businessDta')... 

当社のボルト言語は特別なショートカットを持っているあなたがそこにrootを使用する場合、それは実際に必要なnewData.parent().parent()...呼び出しを生成します。君は。

0

この問題が発生したため、アップデートの各パスのセキュリティルールを修正して解決しました。 SDKは、update()とセキュリティルールでうまくいきます。

あなたの場合は、と/customers/customerIdの両方のセキュリティルールがupdate()コールでうまく機能していることを再度確認したい場合があります。すべての単一の更新パスがルールで動作しているかどうかをテストするために、元のset()を呼び出して、このエラーをデバッグすることができます。

ただし、「/ accounts/$ accountId」のルールに誤字があると思います。 data.child("users")の代わりにroot.child("users")を実行する必要があります

関連する問題