Convalida dei dati

Puoi utilizzare Firebase Security Rules per scrivere in modo condizionale nuovi dati in base a quelli esistenti nel tuo database o bucket di archiviazione. Puoi anche scrivere regole che impongono convalide dei dati limitandone le scritture in base ai nuovi dati scritti. Continua a leggere per scoprire di più sulle regole che utilizzano i dati esistenti per creare condizioni di sicurezza.

Seleziona un prodotto in ogni sezione per scoprire di più sulle regole di convalida dei dati.

Restrizioni relative ai nuovi dati

Cloud Firestore

Se vuoi assicurarti che un documento che contiene un campo specifico non sia puoi includere il campo nella condizione allow. Ad esempio, se vuoi negare la creazione di documenti contenenti il campo ranking, non lo dovrai consentire nella condizione create.

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

Realtime Database

Per fare in modo che i dati che contengono determinati valori non vengano aggiunti al database, includevi quel valore nelle regole e non consentirlo per scrive. Ad esempio, se vuoi rifiutare tutte le scritture che contengono ranking non consentite, le scritture per 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')
    }
  }

Cloud Storage

Se vuoi assicurarti che un file contenente metadati specifici non sia puoi includere i metadati nella condizione allow. Ad esempio, se vuoi negare la creazione di file contenenti metadati ranking, lo disattivi 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 in Firebase Security Rules

Cloud Firestore

Molte app memorizzano le informazioni di controllo dell'accesso come campi sui documenti nel database. Cloud Firestore Security Rules può consentire o negare dinamicamente l'accesso in base al documento dati:

  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 fa riferimento al documento richiesto, mentre resource.data è una mappa di tutti i campi e i valori archiviati nel documento. Per maggiori informazioni informazioni sulla variabile resource, consulta il riferimento documentazione.

Durante la scrittura dei dati, è consigliabile confrontare i dati in entrata con quelli esistenti. Questo ti consente di verificare che un campo non sia stato modificato, che sia stato incrementato di uno o che il nuovo valore sia nel futuro di almeno una settimana. In questo caso, se il set di regole consente la scrittura in attesa, request.resource contiene lo stato futuro del documento. Per le operazioni update che solo modificherà un sottoinsieme dei campi del documento, la variabile request.resource contengono lo stato del documento "In sospeso" dopo l'operazione. Puoi controllare il campo valori in request.resource per impedire aggiornamenti indesiderati o incoerenti dei dati:

   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;
      }
    }
  }

Realtime Database

In Realtime Database, utilizza le regole .validate per applicare le strutture di dati e convalidare il formato e i contenuti dei dati. Rules esegue .validate regole dopo verificando che una regola .write conceda l'accesso.

Le regole .validate non vengono applicate a cascata. Se una qualsiasi regola di convalida ha esito negativo su qualsiasi o percorso secondario nella regola, l'intera operazione di scrittura verrà rifiutata. Inoltre, le definizioni di convalida verificano solo i valori non nulli. e successivamente ignorare le richieste che eliminano i dati.

Considera le seguenti regole di .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()"
        }
      }
    }
  }

Le richieste di scrittura a un database con le regole riportate sopra avranno 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);
Objective-C
Nota: questo prodotto Firebase non è disponibile nel target dell'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];
Swift
Nota: questo prodotto Firebase non è disponibile come target di 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);
Java
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);
REST
# 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

Cloud Storage

Quando valuti le regole, ti consigliamo di valutare anche i metadati del file caricato, scaricato, modificato o eliminato. Questo consente di creare regole complesse ed efficaci, ad esempio consentire solo i file con tipi di contenuti da caricare o solo i file di dimensioni superiori a una determinata dimensione eliminati.

L'oggetto resource contiene coppie chiave/valore con i metadati del file visualizzati in un oggetto Cloud Storage. Queste proprietà possono essere ispezionate su read o Richieste di write per garantire l'integrità dei dati. L'oggetto resource controlla i metadati sui file esistenti nel tuo 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 utilizzare l'oggetto request.resource anche nelle richieste write (ad esempio caricamenti, aggiornamenti ed eliminazioni dei metadati. L'oggetto request.resource ottiene metadati dal file che verranno scritti se write è consentito.

Puoi utilizzare questi due valori per impedire aggiornamenti indesiderati o incoerenti o per applicare vincoli dell'applicazione, come tipo di file o dimensioni.

  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.