Data de validade

Você pode usar as regras de segurança do Firebase para gravar novos dados condicionalmente com base nos dados existentes em seu banco de dados ou bucket de armazenamento. Você também pode escrever regras que imponham validações de dados restringindo gravações com base nos novos dados que estão sendo gravados. Continue lendo para saber mais sobre regras que usam dados existentes para criar condições de segurança.

Selecione um produto em cada seção para saber mais sobre regras de validação de dados.

Restrições sobre novos dados

Cloud Fire Store

Se quiser ter certeza de que um documento que contém um campo específico não será criado, você poderá incluir o campo na condição allow . Por exemplo, se quiser negar a criação de quaisquer documentos que contenham o campo ranking , você deverá proibi-lo na condição create .

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

Banco de dados em tempo real

Se você quiser ter certeza de que os dados que contêm determinados valores não serão adicionados ao seu banco de dados, você incluiria esse valor em suas regras e não permitiria gravações. Por exemplo, se quiser negar qualquer gravação que contenha valores ranking , você deverá proibir gravações para quaisquer documentos com valores 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')
    }
  }

Armazenamento na núvem

Se quiser ter certeza de que um arquivo que contém metadados específicos não será criado, você poderá incluir os metadados na condição allow . Por exemplo, se você quiser negar a criação de qualquer arquivo que contenha metadados ranking , você deverá proibi-lo na condição create .

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

Use dados existentes nas regras de segurança do Firebase

Cloud Fire Store

Muitos aplicativos armazenam informações de controle de acesso como campos em documentos no banco de dados. As regras de segurança do Cloud Firestore podem permitir ou negar acesso dinamicamente com base nos dados do 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';
      }
    }
  }

A variável resource refere-se ao documento solicitado e resource.data é um mapa de todos os campos e valores armazenados no documento. Para obter mais informações sobre a variável resource , consulte a documentação de referência .

Ao gravar dados, você pode querer comparar os dados recebidos com os dados existentes. Isso permite que você faça coisas como garantir que um campo não tenha sido alterado, que um campo tenha aumentado apenas em um ou que o novo valor seja pelo menos uma semana no futuro. Neste caso, se o seu conjunto de regras permitir a gravação pendente, a variável request.resource conterá o estado futuro do documento. Para operações update que modificam apenas um subconjunto dos campos do documento, a variável request.resource conterá o estado do documento pendente após a operação. Você pode verificar os valores dos campos em request.resource para evitar atualizações de dados indesejadas ou inconsistentes:

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

Banco de dados em tempo real

No Realtime Database, use regras .validate para impor estruturas de dados e validar o formato e o conteúdo dos dados. As regras executam regras .validate após verificar se uma regra .write concede acesso.

As regras .validate não são cascatas. Se alguma regra de validação falhar em qualquer caminho ou subcaminho da regra, toda a operação de gravação será rejeitada. Além disso, as definições de validação verificam apenas valores não nulos e, subsequentemente, ignoram quaisquer solicitações que estejam excluindo dados.

Considere as seguintes regras .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()"
        }
      }
    }
  }

Escrever solicitações em um banco de dados com as regras acima teria os seguintes resultados:

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);
Objetivo-C
Observação: este produto do Firebase não está disponível no destino 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];
Rápido
Observação: este produto do Firebase não está disponível no destino 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);
DESCANSAR
# 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

Armazenamento na núvem

Ao avaliar regras, você também pode avaliar os metadados do arquivo que está sendo carregado, baixado, modificado ou excluído. Isso permite que você crie regras complexas e poderosas que fazem coisas como permitir apenas o upload de arquivos com determinados tipos de conteúdo ou apenas a exclusão de arquivos maiores que um determinado tamanho.

O objeto resource contém pares de chave/valor com metadados de arquivo exibidos em um objeto do Cloud Storage. Essas propriedades podem ser inspecionadas em solicitações read ou write para garantir a integridade dos dados. O objeto resource verifica metadados em arquivos existentes no bucket do 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';
        }
      }
    }
  }

Você também pode usar o objeto request.resource em solicitações write (como uploads, atualizações de metadados e exclusões. O objeto request.resource obtém metadados do arquivo que será gravado se a write for permitida.

Você pode usar esses dois valores para evitar atualizações indesejadas ou inconsistentes ou para impor restrições de aplicativo, como tipo ou tamanho de arquivo.

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

Uma lista completa de propriedades no objeto resource está disponível na documentação de referência .