Com o Cloud Firestore Security Rules, é possível controlar o acesso a documentos e coleções no seu banco de dados. Usando a sintaxe de regras flexíveis, você pode criar regras que correspondem a várias operações, de todas as gravações em todo o banco de dados até operações em um documento específico.
Veja neste guia a sintaxe básica e a estrutura das regras de segurança. Use esta sintaxe com as condições de regras de segurança para criar conjuntos de regras completos.
Declaração de serviço e banco de dados
As Cloud Firestore Security Rules sempre começam com a seguinte declaração:
service cloud.firestore {
// The {database} wildcard allows the rules to reference any database,
// but these rules are only active on databases where they are explicitly deployed.
match /databases/{database}/documents {
// ...
}
}
A declaração service cloud.firestore define o escopo das regras do Cloud Firestore, evitando conflitos entre Cloud Firestore Security Rules e as regras de outros produtos, como o Cloud Storage.
A declaração match /databases/{database}/documents especifica que as regras devem corresponder a qualquer banco de dados do Cloud Firestore no projeto. Um projeto pode conter até 100 bancos de dados, mas apenas o primeiro criado é designado como padrão.
Cloud Firestore Security Rules são aplicados separadamente a cada banco de dados nomeado no seu projeto. Isso significa que, se você criar vários bancos de dados, precisará gerenciar e implantar regras para cada um deles individualmente. Para instruções detalhadas sobre como implantar suas atualizações, consulte Implantar suas atualizações.
Regras básicas de leitura e gravação
As regras básicas consistem em uma instrução match que especifica um caminho de documento e uma expressão allow que, por sua vez, detalha quando a leitura dos dados especificados é permitida:
service cloud.firestore {
match /databases/{database}/documents {
// Match any document in the 'cities' collection
match /cities/{city} {
allow read: if <condition>;
allow write: if <condition>;
}
}
}
Todas as instruções de correspondência devem se referir a documentos e não coleções. Uma instrução de correspondência pode indicar um documento específico, como em match /cities/SF, ou usar caracteres curingas para indicar qualquer documento no caminho especificado, como em match /cities/{city}.
No exemplo acima, a instrução de correspondência usa a sintaxe com caractere curinga {city}.
Isso significa que a regra se aplica a qualquer documento na coleção cities, como
/cities/SF ou /cities/NYC. Quando as expressões allow na instrução de correspondência forem
avaliadas, a variável city resultará no nome do documento da cidade,
como SF ou NYC.
Operações específicas
Em algumas situações, é útil dividir read e write em operações mais granulares. Por exemplo, você pode aplicar condições diferentes para a criação e a exclusão de documentos no seu app. Se preferir, permita leituras de documentos únicos, mas negue grandes consultas.
Uma regra read pode ser dividida em get e list, enquanto uma regra write pode ser dividida em create, update e delete:
service cloud.firestore {
match /databases/{database}/documents {
// A read rule can be divided into get and list rules
match /cities/{city} {
// Applies to single document read requests
allow get: if <condition>;
// Applies to queries and collection read requests
allow list: if <condition>;
}
// A write rule can be divided into create, update, and delete rules
match /cities/{city} {
// Applies to writes to nonexistent documents
allow create: if <condition>;
// Applies to writes to existing documents
allow update: if <condition>;
// Applies to delete operations
allow delete: if <condition>;
}
}
}
Dados hierárquicos
Os dados no Cloud Firestore são organizados em coleções de documentos, e cada documento pode estender a hierarquia por meio de subcoleções. É importante entender como as regras de segurança interagem com dados hierárquicos.
Considere a situação em que cada documento na coleção cities contém uma
subcoleção landmarks. As regras de segurança se aplicam somente ao caminho correspondente, de modo que
os controles de acesso definidos na coleção cities não se aplicam à
subcoleção landmarks. Em vez disso, escreva regras explícitas para controlar o acesso
a subcoleções:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
allow read, write: if <condition>;
// Explicitly define rules for the 'landmarks' subcollection
match /landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
}
Ao aninhar instruções match, o caminho da instrução match interna é sempre
relativo ao caminho da instrução match externa. Os seguintes conjuntos de regras
são equivalentes:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
match /landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
}
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city}/landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
Caracteres curinga recursivos
Se você quer aplicar regras a uma hierarquia arbitrariamente profunda, use a sintaxe de caractere curinga recorrente, {name=**}. Exemplo:
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{document=**} {
allow read, write: if <condition>;
}
}
}
Ao usar a sintaxe com caractere curinga recorrente, a variável dele terá todo o segmento do caminho de correspondência, mesmo que o documento esteja localizado em uma subcoleção aninhada em vários níveis. Por exemplo, as regras listadas acima corresponderiam
a um documento localizado em /cities/SF/landmarks/coit_tower, e o valor
da variável document seria SF/landmarks/coit_tower.
No entanto, o comportamento de caracteres curinga recursivos depende da versão das regras.
Versão 1
As regras de segurança usam a versão 1 por padrão. Nela, os caracteres curinga recursivos
correspondem a um ou mais itens de caminho. Eles não correspondem a um caminho vazio, por isso
match /cities/{city}/{document=**} corresponde aos documentos em subcoleções, mas
não na coleção cities, enquanto match /cities/{document=**} corresponde
a ambos os documentos na coleção cities e nas subcoleções.
Os caracteres curinga recursivos precisam aparecer no fim de uma instrução de correspondência.
Versão 2
Na versão 2 das regras de segurança, caracteres curingas recorrentes correspondem a zero ou mais itens
de caminho. match/cities/{city}/{document=**} corresponde a documentos em todas as
subcoleções, bem como aos documentos na coleção cities.
Você deve ativar a versão 2 adicionando rules_version = '2'; na parte de cima das
suas regras de segurança:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{city}/{document=**} {
allow read, write: if <condition>;
}
}
}
É permitido ter no máximo um caractere curinga recursivo por instrução de correspondência. No entanto, na versão 2, é possível posicioná-lo em qualquer lugar da instrução. Exemplo:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the songs collection group
match /{path=**}/songs/{song} {
allow read, write: if <condition>;
}
}
}
Se você usar consultas do grupo de coleções, será necessário utilizar a versão 2. Consulte Como proteger as consultas do grupo de coleções.
Sobreposição de instruções de correspondência
É possível que um documento corresponda a mais de uma instrução match. No caso de
várias expressões allow corresponderem a uma solicitação, o acesso será permitido
se qualquer uma das condições for true:
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the 'cities' collection.
match /cities/{city} {
allow read, write: if false;
}
// Matches any document in the 'cities' collection or subcollections.
match /cities/{document=**} {
allow read, write: if true;
}
}
}
No exemplo acima, todas as leituras e gravações da coleção cities serão
permitidas porque a segunda regra é sempre true, mesmo que a primeira
regra seja sempre false.
Limites da regra de segurança
Ao trabalhar com regras de segurança, observe os seguintes limites:
| Limite | Detalhes |
|---|---|
Número máximo de chamadas exists(), get() e getAfter() por solicitação. |
Ao exceder qualquer um desses limites, ocorrerá um erro de permissão negada. Algumas chamadas de acesso a documentos podem ser armazenadas em cache. Elas não entram na conta dos limites. |
Máxima profundidade da instrução match aninhada |
10 |
Tamanho do caminho máximo, em segmentos de caminho, permitido em um grupo de instruções
match aninhadas |
100 |
Número máximo de variáveis de captura de caminho permitidas em um conjunto de
instruções match aninhadas |
20 |
| Profundidade máxima da chamada da função | 20 |
| Número máximo de argumentos de função | 7 |
Número máximo de vinculações de variáveis let por função |
10 |
| Número máximo de chamadas de função recorrentes ou cíclicas | 0 (não permitido) |
| Número máximo de expressões avaliadas por solicitação | 1.000 |
| Tamanho máximo de um conjunto de regras | Os conjuntos de regras precisam atender a dois limites de tamanho:
|