2016-03-23 13 views
1

Firebase.update() ist sehr nützlich, um mehrere Knoten atomar zu aktualisieren. Es scheint jedoch begrenzt zu sein, da die Sicherheitsregeln immer noch vom Stammknoten in der Operation update() definiert sind.Granulare Firebase-Sicherheit für update() Anruf

Zum Beispiel lassen Sie uns sagen, dass meine Daten ist wie:

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

My Firebase Sicherheit wie organisiert ist:

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

Um ein Atom Update für einen bestimmten BusinessID über diesen Knoten zu machen, ich kann ein update() Anruf als solche machen:

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

Seit update() sollte nur die angegebenen Speicherorte ändern, können die Knoten-für-Knoten-Sicherheitsregeln gelten (z. mit uid). Allerdings scheint es, dass die Wurzel Sicherheit (zB /) herrscht, und ich bekomme eine Warnung als solche:

FIREBASE WARNING: update at/failed: permission_denied 

So, jetzt bin ich stattdessen ein Versprechen Kette mit den verschiedenen Knoten in der Folge zu aktualisieren set() mit was bedeutet, mich Verliere die atomare Operation.

Gibt es eine bessere Möglichkeit, atomare Operationen über mehrere Knoten hinweg durchzuführen, ohne die Sicherheit für den Root zu öffnen?

+1

tun Können Sie bitte Ihre Regeln (als Text) für die oben genannte Firebase-Struktur? – Jay

+0

Hallo Jay! Entschuldigung für die späte Antwort. Meine Anwendung ist ein wenig zu komplex, um die vollständigen Sicherheitsregeln zu posten, und mir fiel keine einfache Möglichkeit zur Replizierung des Problems ein. Aber sollte generell ein Aufruf von update() am Root-Knoten funktionieren, wenn alle aktualisierten Sub-Knoten die Sicherheit bestehen? Wenn das der Fall ist, ist es wahrscheinlich eine falsche Sicherheitseinstellung in meinem Namen. –

+0

hast du das Problem gelöst? – Ymmanuel

Antwort

0

In Ihren Sicherheitsregeln bezieht sich root auf die aktuellen/alten Daten im Stammverzeichnis. Wenn Sie die neuen Daten an der Wurzel zugreifen möchten, müssen Sie von newData dorthin navigieren:

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

Unsere Bolt Sprache hat eine spezielle Verknüpfung, wenn Sie root dort wird es tatsächlich die notwendigen newData.parent().parent()... Anrufe generieren für Sie.

0

Ich bin auf dieses Problem gestoßen und habe es gelöst, indem ich die Sicherheitsregeln für jeden Pfad in den Updates festgelegt habe. Stellt sich heraus, das SDK funktioniert gut mit den update() und Sicherheitsregeln.

Für Ihren Fall, möchten Sie vielleicht überprüfen Sie die Sicherheitsregeln für beide /accounts/accountId und /customers/customerId funktionieren gut für Ihre update() Anruf. Sie können dies debuggen, indem Sie das Update in den ursprünglichen set() Aufruf trennen, um zu testen, ob jeder einzelne Aktualisierungspfad mit den Regeln arbeitet.

Allerdings denke ich, dass Sie einen Tippfehler in den Regeln von "/ accounts/$ accountId" haben können. Möglicherweise müssen Sie root.child("users") anstelle von data.child("users")