2016-08-22 1 views
4

Vielleicht bin ich dieses Problem zu viel aus einer SQL-Perspektive, aber ich habe Probleme zu verstehen, wie Sie ordnungsgemäß einschränken, welche Kinder einen Knoten bevölkern dürfen."Catch all anderen" Firebase-Datenbankregel

Angenommen, ich möchte Produkte mit beliebigen Namen registrieren. Jedes Produkt muss eine price enthalten, aber nichts anderes ist erlaubt.

Mein naiver Ansatz war eine .validate Regel zu den Produkten hinzuzufügen newData erfordern ein price Kind zu enthalten, explizit Schreibzugriff auf die price Knoten gewährt und dann Entfernen all Zugriff auf einen $other Knoten (etwa wie eine Standard-Klausel in einer switch-Anweisung):

{ 
    "rules": { 
     "$product": { 
      ".read": true, 
      ".write": true, 
      ".validate": "newData.hasChildren(['price'])", 
      "price": { 
       ".write": true, 
       ".validate": "newData.isNumber()" 
      }, 
      "$other": { 
       ".read.": false, 
       ".write": false, 
      } 
     } 
    } 
} 

Dies funktioniert nicht. Das Hinzufügen eines neuen Produkts mit {"price": 1234, "foo": "bar"} wird weiterhin akzeptiert. Wenn ich jedoch eine ".validate": false Regel zu $other hinzufüge, wird stattdessen nichts akzeptiert (z. B. ist nicht erlaubt).(Ich habe das falsch gemacht, irgendwie.)

Gibt es eine Möglichkeit, etwas ähnliches zu implementieren, was ich hier versuche? Wenn nicht, wie kann eine Datenstruktur in Firebase eingeschränkt werden? Sollte ich es überhaupt tun? Was hält den Benutzer davon ab, meine Datenbank mit Müll zu füllen, wenn ich das nicht tue?

+0

Ich bin nicht sicher, ich folge, warum '„$ andere“: {„.validate“: false}' ist nicht das, was Sie wollen. Ist Ihnen jedoch bewusst, dass Sie eine einmal erteilte Erlaubnis nicht widerrufen können? Also bedeutet '' write ": true' unter' $ product', dass Ihr '" .write ": false' unter' $ other' ignoriert wird? – cartant

+0

@cartant Ich habe die Frage aktualisiert, um zu klären, warum validate nicht funktioniert. –

Antwort

7

Sie fallen hier in ein paar gemeinsame Firebase Security Pits. Am gebräuchlichsten ist, dass die Berechtigung kaskadiert: Sobald Sie auf einer bestimmten Ebene in der Baumstruktur Lese- oder Schreibrechte erteilt haben, können Sie diese Berechtigung nicht auf einer niedrigeren Ebene entfernen.

Das bedeutet, dass diese Regeln unwirksam sind (da Sie gewährt Lese-/Schreib eine Ebene höher haben bereits):

"$other": { 
    ".read.": false, 
    ".write": false, 
} 

Um das Problem zu lösen, müssen Sie erkennen, dass .validate Regeln unterschiedlich sind: Daten gilt nur dann als gültig, wenn alle Validierungsregeln erfüllt sind. So können Sie die $other Daten mit einem Validierungsregeln ablehnen:

{ 
    "rules": { 
     "$product": { 
      ".read": true, 
      ".write": true, 
      ".validate": "newData.hasChildren(['price'])", 
      "price": { 
       ".validate": "newData.isNumber()" 
      }, 
      "$other": { 
       ".validate": false 
      } 
     } 
    } 
} 
+0

Das löst es. Das Lustige ist, dass ich dachte, ich hätte genau diese Lösung ausprobiert (wie ich in der Frage kurz erwähnt habe), aber anscheinend habe ich es geschafft, das irgendwie zu verpfuschen. So oder so, Ihre Antwort machte auch die Unterschiede zwischen validieren und schreiben viel klarer zu mir, also vielen Dank dafür. :) –

+0

Wie würde das in Bolzen aussehen? – Waltari

Verwandte Themen