Convalida dei dati

Puoi utilizzare le regole di sicurezza Firebase per scrivere nuovi dati in modo condizionale in base ai dati esistenti nel database o nel bucket di archiviazione. È inoltre possibile scrivere regole che impongano la convalida dei dati limitando le scritture in base ai nuovi dati scritti. Continua a leggere per saperne di più sulle regole che utilizzano i dati esistenti per creare condizioni di sicurezza.

Seleziona un prodotto in ciascuna sezione per saperne di più sulle regole di convalida dei dati.

Restrizioni sui nuovi dati

Cloud Fire Store

Se vuoi assicurarti che un documento che contiene un campo specifico non venga creato, puoi includere il campo nella condizione allow . Ad esempio, se desideri negare la creazione di documenti che contengono il campo ranking , non consentirlo nella condizione create .

  service cloud.firestore {
    match /databases/{database}/documents {
      // Disallow
      match /cities/{city} {
        allow create: if !("ranking" in request.resource.data)
      }
    }
  }

Banca dati in tempo reale

Se vuoi assicurarti che i dati che contengono determinati valori non vengano aggiunti al tuo database, includi quel valore nelle tue regole e non consentirlo per le scritture. Ad esempio, se desideri negare qualsiasi scrittura che contenga valori ranking , non consentiresti le scritture per tutti i documenti con valori ranking .

  {
    "rules": {
      // Write is allowed for all paths
      ".write": true,
      // Allows writes only if new data doesn't include a `ranking` child value
      ".validate": "!newData.hasChild('ranking')
    }
  }

Archiviazione nel cloud

Se vuoi assicurarti che non venga creato un file che contiene metadati specifici, puoi includere i metadati nella condizione allow . Ad esempio, se desideri negare la creazione di file che contengono metadati ranking , non consentirlo nella condizione create .

  service firebase.storage {
    match /b/{bucket}/o {
      match /files/{allFiles=**} {
      // Disallow
        allow create: if !("ranking" in request.resource.metadata)
      }
    }
  }

Utilizza i dati esistenti nelle regole di sicurezza Firebase

Cloud Fire Store

Molte app archiviano le informazioni sul controllo degli accessi come campi sui documenti nel database. Le regole di sicurezza di Cloud Firestore possono consentire o negare dinamicamente l'accesso in base ai dati del documento:

  service cloud.firestore {
    match /databases/{database}/documents {
      // Allow the user to read data if the document has the 'visibility'
      // field set to 'public'
      match /cities/{city} {
        allow read: if resource.data.visibility == 'public';
      }
    }
  }

La variabile resource si riferisce al documento richiesto e resource.data è una mappa di tutti i campi e i valori archiviati nel documento. Per ulteriori informazioni sulla variabile resource , consultare la documentazione di riferimento .

Durante la scrittura dei dati, potresti voler confrontare i dati in arrivo con i dati esistenti. Ciò ti consente di fare cose come assicurarti che un campo non sia cambiato, che un campo sia aumentato solo di uno o che il nuovo valore sia almeno una settimana nel futuro. In questo caso, se il tuo set di regole consente la scrittura in sospeso, la variabile request.resource contiene lo stato futuro del documento. Per le operazioni update che modificano solo un sottoinsieme dei campi del documento, la variabile request.resource conterrà lo stato del documento in sospeso dopo l'operazione. Puoi controllare i valori dei campi in request.resource per evitare aggiornamenti di dati indesiderati o incoerenti:

   service cloud.firestore {
     match /databases/{database}/documents {
      // Make sure all cities have a positive population and
      // the name is not changed
      match /cities/{city} {
        allow update: if request.resource.data.population > 0
                      && request.resource.data.name == resource.data.name;
      }
    }
  }

Banca dati in tempo reale

In Realtime Database, utilizza le regole .validate per applicare strutture di dati e convalidare il formato e il contenuto dei dati. Le regole eseguono le regole .validate dopo aver verificato che una regola .write concede l'accesso.

Le regole .validate non si applicano a cascata. Se una qualsiasi regola di convalida fallisce su qualsiasi percorso o sottopercorso nella regola, l'intera operazione di scrittura verrà rifiutata. Inoltre, le definizioni di convalida controllano solo i valori non nulli e successivamente ignorano qualsiasi richiesta che stia eliminando dati.

Considera le seguenti regole .validate :

  {
    "rules": {
      // write is allowed for all paths
      ".write": true,
      "widget": {
        // a valid widget must have attributes "color" and "size"
        // allows deleting widgets (since .validate is not applied to delete rules)
        ".validate": "newData.hasChildren(['color', 'size'])",
        "size": {
          // the value of "size" must be a number between 0 and 99
          ".validate": "newData.isNumber() &&
                        newData.val() >= 0 &&
                        newData.val() <= 99"
        },
        "color": {
          // the value of "color" must exist as a key in our mythical
          // /valid_colors/ index
          ".validate": "root.child('valid_colors/' + newData.val()).exists()"
        }
      }
    }
  }

Scrivere richieste in un database con le regole di cui sopra avrebbe i seguenti risultati:

JavaScript
var ref = db.ref("/widget");

// PERMISSION_DENIED: does not have children color and size
ref.set('foo');

// PERMISSION DENIED: does not have child color
ref.set({size: 22});

// PERMISSION_DENIED: size is not a number
ref.set({ size: 'foo', color: 'red' });

// SUCCESS (assuming 'blue' appears in our colors list)
ref.set({ size: 21, color: 'blue'});

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
ref.child('size').set(99);
Obiettivo-C
Nota: questo prodotto Firebase non è disponibile nella destinazione App Clip.
FIRDatabaseReference *ref = [[[FIRDatabase database] reference] child: @"widget"];

// PERMISSION_DENIED: does not have children color and size
[ref setValue: @"foo"];

// PERMISSION DENIED: does not have child color
[ref setValue: @{ @"size": @"foo" }];

// PERMISSION_DENIED: size is not a number
[ref setValue: @{ @"size": @"foo", @"color": @"red" }];

// SUCCESS (assuming 'blue' appears in our colors list)
[ref setValue: @{ @"size": @21, @"color": @"blue" }];

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
[[ref child:@"size"] setValue: @99];
Veloce
Nota: questo prodotto Firebase non è disponibile nella destinazione App Clip.
var ref = FIRDatabase.database().reference().child("widget")

// PERMISSION_DENIED: does not have children color and size
ref.setValue("foo")

// PERMISSION DENIED: does not have child color
ref.setValue(["size": "foo"])

// PERMISSION_DENIED: size is not a number
ref.setValue(["size": "foo", "color": "red"])

// SUCCESS (assuming 'blue' appears in our colors list)
ref.setValue(["size": 21, "color": "blue"])

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
ref.child("size").setValue(99);
Giava
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("widget");

// PERMISSION_DENIED: does not have children color and size
ref.setValue("foo");

// PERMISSION DENIED: does not have child color
ref.child("size").setValue(22);

// PERMISSION_DENIED: size is not a number
Map<String,Object> map = new HashMap<String, Object>();
map.put("size","foo");
map.put("color","red");
ref.setValue(map);

// SUCCESS (assuming 'blue' appears in our colors list)
map = new HashMap<String, Object>();
map.put("size", 21);
map.put("color","blue");
ref.setValue(map);

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
ref.child("size").setValue(99);
RIPOSO
# PERMISSION_DENIED: does not have children color and size
curl -X PUT -d 'foo' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# PERMISSION DENIED: does not have child color
curl -X PUT -d '{"size": 22}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# PERMISSION_DENIED: size is not a number
curl -X PUT -d '{"size": "foo", "color": "red"}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# SUCCESS (assuming 'blue' appears in our colors list)
curl -X PUT -d '{"size": 21, "color": "blue"}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# If the record already exists and has a color, this will
# succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
# will fail to validate
curl -X PUT -d '99' \
https://docs-examples.firebaseio.com/rest/securing-data/example/size.json

Archiviazione nel cloud

Quando valuti le regole, potresti anche voler valutare i metadati del file che viene caricato, scaricato, modificato o eliminato. Ciò ti consente di creare regole complesse e potenti che fanno cose come consentire solo il caricamento di file con determinati tipi di contenuto o l'eliminazione solo di file più grandi di una certa dimensione.

L'oggetto resource contiene coppie chiave/valore con metadati di file visualizzati in un oggetto Cloud Storage. Queste proprietà possono essere ispezionate durante le richieste di read o write per garantire l'integrità dei dati. L'oggetto resource controlla i metadati sui file esistenti nel bucket Cloud Storage.

  service firebase.storage {
    match /b/{bucket}/o {
      match /images {
        match /{allImages=**} {
          // Allow reads if a custom 'visibility' field is set to 'public'
          allow read: if resource.metadata.visibility == 'public';
        }
      }
    }
  }

Puoi anche utilizzare l'oggetto request.resource sulle richieste write (come caricamenti, aggiornamenti di metadati ed eliminazioni. L'oggetto request.resource ottiene i metadati dal file che verrà scritto se la write è consentita.

È possibile utilizzare questi due valori per impedire aggiornamenti indesiderati o incoerenti o per imporre vincoli dell'applicazione, ad esempio il tipo o la dimensione del file.

  service firebase.storage {
    match /b/{bucket}/o {
      match /images {
        // Cascade read to any image type at any path
        match /{allImages=**} {
          allow read;
        }

        // Allow write files to the path "images/*", subject to the constraints:
        // 1) File is less than 5MB
        // 2) Content type is an image
        // 3) Uploaded content type matches existing content type
        // 4) File name (stored in imageId wildcard variable) is less than 32 characters
        match /{imageId} {
          allow write: if request.resource.size < 5 * 1024 * 1024
                       && request.resource.contentType.matches('image/.*')
                       && request.resource.contentType == resource.contentType
                       && imageId.size() < 32
        }
      }
    }
  }

Un elenco completo delle proprietà nell'oggetto resource è disponibile nella documentazione di riferimento .