Ir para o console

Validação de dados

É possível usar as regras de segurança do Firebase para gravar, de modo condicional, novos dados com base nas informações presentes no banco de dados ou no intervalo de armazenamento. Além disso, é possível gravar regras que apliquem validações de dados por meio da restrição de gravações com base nos novos dados que estão sendo gravados. Continue lendo para saber mais sobre as regras que usam dados atuais para criar condições de segurança.

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

Restrições a novos dados

Cloud Firestore

Se você quiser garantir que um documento que contém um campo específico não seja criado, inclua esse campo na condição allow. Por exemplo, se você quiser negar a criação de qualquer documento que contenha o campo ranking, bloqueie-o na condição create.

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

Realtime Database

Se você quiser garantir que as informações que contêm determinados valores não sejam adicionadas ao seu banco de dados, inclua esses valores nas regras e bloqueie a gravação delas. Por exemplo, se você quiser negar qualquer gravação que contenha os valores de ranking, bloqueie as gravações de qualquer documento com os valores de 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 você quiser garantir que um arquivo que contém metadados específicos não seja criado, inclua esses metadados na condição allow. Por exemplo, se quiser negar a criação de qualquer arquivo que contenha metadados de ranking, bloqueie-os na condição create.

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

Usar dados atuais nas regras de segurança do Firebase

Cloud Firestore

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 mais informações sobre a variável resource, consulte a documentação de referência.

Ao gravar dados, pode ser necessário comparar as informações novas com as existentes. Dessa forma, é possível garantir, por exemplo, que um campo não seja alterado, que ele tenha o valor incrementado em apenas um ou que o novo valor esteja pelo menos uma semana no futuro. Nesse caso, se o conjunto de regras permitir a gravação pendente, a variável request.resource conterá o estado futuro do documento. Para operações update que apenas modificam um subconjunto dos campos do documento, a variável request.resource conterá o estado do documento pendente após a operação. É possível verificar os valores do campo 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;
      }
    }
  }

Realtime Database

No Realtime Database, use regras .validate para aplicar estruturas de dados e validar o formato e o conteúdo deles. As regras executam regras .validate depois de verificar se .write concedeu acesso.

As regras .validate não estão em cascata. Se qualquer regra de validação falhar em qualquer caminho ou subcaminho, a operação de gravação como um todo será recusada. Além disso, as definições de validação verificam se há apenas valores não nulos e, em seguida, ignora qualquer solicitação que exclua dados.

Veja estes exemplos de 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()"
        }
      }
    }
  }

As solicitações de gravação para um banco de dados que use as regras acima teriam 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);
Objective-C
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
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

Durante a avaliação de regras, é possível também examinar os metadados do arquivo que está sendo modificado, excluído ou transferido por upload ou download. Isso permite criar regras eficazes e complexas que realizem operações como permitir apenas que arquivos com determinados tipos de conteúdo sejam enviados ou que apenas arquivos acima de certo tamanho sejam excluídos.

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

Também é possível usar o objeto request.resource em solicitações write (como uploads, atualizações de metadados e exclusões). O objeto request.resource acessará os metadados do arquivo que será gravado se write for permitida.

Use esses dois valores para impedir atualizações não solicitadas ou inconsistentes ou para aplicar 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
        }
      }
    }
  }

Há uma lista completa das propriedades do objeto resource disponível na documentação de referência.