As regras de segurança do Cloud Firestore permitem controlar o acesso a documentos e coleções em seu banco de dados. A sintaxe de regras flexível permite criar regras que correspondem a qualquer coisa, desde todas as gravações em todo o banco de dados até operações em um documento específico.
Este guia descreve a sintaxe básica e a estrutura das regras de segurança. Combine esta sintaxe com condições de regras de segurança para criar conjuntos de regras completos.
Declaração de serviço e banco de dados
As regras de segurança do Cloud Firestore sempre começam com a seguinte declaração:
service cloud.firestore {
match /databases/{database}/documents {
// ...
}
}
A declaração service cloud.firestore
abrange as regras do Cloud Firestore, evitando conflitos entre as regras de segurança do Cloud Firestore 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. Atualmente cada projeto possui apenas um único banco de dados denominado (default)
.
Regras básicas de leitura/gravação
As regras básicas consistem em uma instrução match
especificando um caminho de documento e uma expressão allow
detalhando 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 declarações de correspondência devem apontar para documentos, não para coleções. Uma instrução match pode apontar para um documento específico, como em match /cities/SF
ou usar curingas para apontar para qualquer documento no caminho especificado, como em match /cities/{city}
.
No exemplo acima, a instrução match usa a sintaxe curinga {city}
. Isso significa que a regra se aplica a qualquer documento da coleção cities
, como /cities/SF
ou /cities/NYC
. Quando as expressões allow
na instrução match são avaliadas, a variável city
será resolvida para o nome do documento da cidade, como SF
ou NYC
.
Operações granulares
Em algumas situações, é útil dividir read
e write
em operações mais granulares. Por exemplo, seu aplicativo pode querer impor condições diferentes na criação de documentos e na exclusão de documentos. Ou você pode permitir leituras de documentos únicos, mas negar consultas grandes.
Uma regra de 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 compreender como as regras de segurança interagem com os dados hierárquicos.
Considere a situação em que cada documento da coleção de cities
contém uma subcoleção landmarks
. As regras de segurança aplicam-se apenas ao caminho correspondente, portanto 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 às 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, portanto, 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>;
}
}
}
Curingas recursivos
Se você deseja que as regras sejam aplicadas a uma hierarquia arbitrariamente profunda, use a sintaxe curinga recursiva, {name=**}
. Por 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 curinga recursiva, a variável curinga conterá todo o segmento do caminho correspondente, mesmo se o documento estiver localizado em uma subcoleção profundamente aninhada. 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
.
Observe, entretanto, que o comportamento dos curingas recursivos depende da versão das regras.
Versão 1
As regras de segurança usam a versão 1 por padrão. Na versão 1, os curingas recursivos correspondem a um ou mais itens de caminho. Eles não correspondem a um caminho vazio, portanto, match /cities/{city}/{document=**}
corresponde a documentos em subcoleções, mas não na coleção cities
, enquanto match /cities/{document=**}
corresponde a ambos os documentos no coleção cities
e subcoleções.
Os curingas recursivos devem vir no final de uma instrução de correspondência.
Versão 2
Na versão 2 das regras de segurança, os curingas recursivos correspondem a zero ou mais itens de caminho. match/cities/{city}/{document=**}
corresponde a documentos em qualquer subcoleção, bem como a documentos na coleção cities
.
Você deve aceitar a versão 2 adicionando rules_version = '2';
no topo de 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>;
}
}
}
Você pode ter no máximo um curinga recursivo por instrução de correspondência, mas na versão 2, você pode colocar esse curinga em qualquer lugar da instrução de correspondência. Por 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 de grupo de coleta , deverá usar a versão 2, consulte protegendo consultas de grupo de coleta .
Sobreposição de declarações de correspondência
É possível que um documento corresponda a mais de uma instrução match
. No caso de múltiplas expressões allow
corresponderem a uma solicitação, o acesso será permitido se alguma 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 na coleção cities
serão permitidas porque a segunda regra é sempre true
, mesmo que a primeira regra seja sempre false
.
Limites das regras de segurança
Ao trabalhar com regras de segurança, observe os seguintes limites:
Limite | Detalhes |
---|---|
Número máximo de exists() , get() e getAfter() por solicitação |
Exceder qualquer um dos limites resulta em um erro de permissão negada. Algumas chamadas de acesso a documentos podem ser armazenadas em cache e as chamadas armazenadas em cache não contam para os limites. |
Profundidade máxima da instrução match aninhada | 10 |
Comprimento máximo do caminho, em segmentos de caminho, permitido em um conjunto 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 de chamada de função | 20 |
Número máximo de argumentos de função | 7 |
Número máximo de ligações de variáveis let por função | 10 |
Número máximo de chamadas de função recursivas 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 devem obedecer a dois limites de tamanho:
|
Próximos passos
- Escreva condições de regras de segurança personalizadas .
- Leia a referência de regras de segurança .