La validation des données

Vous pouvez utiliser les règles de sécurité Firebase pour écrire de manière conditionnelle de nouvelles données en fonction des données existantes dans votre base de données ou votre bucket de stockage. Vous pouvez également écrire des règles qui appliquent les validations de données en limitant les écritures en fonction des nouvelles données écrites. Lisez la suite pour en savoir plus sur les règles qui utilisent des données existantes pour créer des conditions de sécurité.

Sélectionnez un produit dans chaque section pour en savoir plus sur les règles de validation des données.

Restrictions sur les nouvelles données

Cloud Firestore

Si vous voulez vous assurer qu'un document contenant un champ spécifique n'est pas créé, vous pouvez inclure le champ dans la allow condition. Par exemple, si vous souhaitez refuser la création de tout document contenant le ranking champ, vous désavouer dans la create condition.

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

Base de données en temps réel

Si vous voulez vous assurer que les données contenant certaines valeurs ne sont pas ajoutées à votre base de données, vous devez inclure cette valeur dans vos règles et l'interdire pour les écritures. Par exemple, si vous souhaitez refuser toute écriture qui contiennent ranking des valeurs, vous désavouer tous les documents pour les écritures avec ranking des valeurs.

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

Stockage en ligne

Si vous voulez vous assurer qu'un fichier contenant des métadonnées spécifiques n'est pas créé, vous pouvez inclure les métadonnées dans la allow condition. Par exemple, si vous souhaitez refuser la création de tous les fichiers qui contiennent ranking des métadonnées, vous désavouer dans la create condition.

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

Utiliser les données existantes dans les règles de sécurité Firebase

Cloud Firestore

De nombreuses applications stockent les informations de contrôle d'accès sous forme de champs sur les documents de la base de données. Les règles de sécurité Cloud Firestore peuvent autoriser ou refuser l'accès de manière dynamique en fonction des données du document :

  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 resource variable fait référence au document demandé et resource.data est une carte de tous les champs et les valeurs stockées dans le document. Pour plus d' informations sur la resource variables, consultez la documentation de référence .

Lors de l'écriture de données, vous souhaiterez peut-être comparer les données entrantes aux données existantes. Cela vous permet, par exemple, de vous assurer qu'un champ n'a pas changé, qu'un champ n'a été incrémenté que de un ou que la nouvelle valeur est au moins une semaine dans le futur. Dans ce cas, si votre ruleset permet l'attente d' écriture, la request.resource variable contient l'état futur du document. Pour la update à request.resource update des opérations qui modifient seulement un sous - ensemble des champs de documents, la request.resource variable contiendra l'état de document en attente après l'opération. Vous pouvez vérifier les valeurs de champ dans request.resource pour éviter les mises à jour de données non désirées ou incohérentes:

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

Base de données en temps réel

Base de données en temps réel, utilisez .validate règles pour appliquer des structures de données et de valider le format et le contenu des données. Les règles fonctionnent .validate règles après avoir vérifié qu'une .write règle autorise l' accès.

Les .validate règles ne sont pas en cascade. Si une règle de validation échoue sur un chemin ou sous-chemin de la règle, l'intégralité de l'opération d'écriture sera rejetée. De plus, les définitions de validation vérifient uniquement les valeurs non NULL et ignorent par la suite toutes les demandes qui suppriment des données.

Considérez ce qui suit .validate règles:

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

Écrire des requêtes dans une base de données avec les règles ci-dessus aurait les résultats suivants :

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);
Objectif c
Note: Ce produit Firebase n'est pas disponible sur la cible Clip App.
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];
Rapide
Note: Ce produit Firebase n'est pas disponible sur la cible Clip App.
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);
DU REPOS
# 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

Stockage en ligne

Lors de l'évaluation des règles, vous souhaiterez peut-être également évaluer les métadonnées du fichier en cours de chargement, de téléchargement, de modification ou de suppression. Cela vous permet de créer des règles complexes et puissantes qui permettent, par exemple, le téléchargement de fichiers avec certains types de contenu ou la suppression de fichiers supérieurs à une certaine taille.

La resource objet contient des paires de clés de la valeur de / avec des métadonnées de fichier surface dans un objet de stockage Cloud. Ces propriétés peuvent être inspectés en read ou write des demandes pour assurer l' intégrité des données. Les resource contrôles d'objet de métadonnées sur les fichiers existants dans votre seau 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';
        }
      }
    }
  }

Vous pouvez également utiliser l' request.resource objet sur write des demandes (telles que les ajouts, les mises à jour des métadonnées et des suppressions. Le request.resource objet métadonnées sont à partir du fichier qui sera écrit si l' write est autorisée.

Vous pouvez utiliser ces deux valeurs pour empêcher les mises à jour indésirables ou incohérentes ou pour appliquer des contraintes d'application, telles que le type ou la taille de fichier.

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

Une liste complète des propriétés dans la resource objet est disponible dans la documentation de référence .