Las reglas de seguridad de Cloud Firestore le permiten controlar el acceso a documentos y colecciones en su base de datos. La sintaxis de reglas flexible le permite crear reglas que coincidan con cualquier cosa, desde todas las escrituras en toda la base de datos hasta operaciones en un documento específico.
Esta guía describe la sintaxis y estructura básicas de las reglas de seguridad. Combine esta sintaxis con condiciones de reglas de seguridad para crear conjuntos de reglas completos.
Declaración de servicio y base de datos.
Las reglas de seguridad de Cloud Firestore siempre comienzan con la siguiente declaración:
service cloud.firestore {
match /databases/{database}/documents {
// ...
}
}
La declaración del service cloud.firestore
aplica las reglas a Cloud Firestore, lo que evita conflictos entre las reglas de seguridad de Cloud Firestore y las reglas de otros productos como Cloud Storage.
La declaración match /databases/{database}/documents
especifica que las reglas deben coincidir con cualquier base de datos de Cloud Firestore en el proyecto. Actualmente, cada proyecto tiene una sola base de datos denominada (default)
.
Reglas básicas de lectura/escritura
Las reglas básicas consisten en una declaración match
que especifica una ruta de documento y una expresión allow
que detalla cuándo se permite la lectura de los datos especificados:
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 las declaraciones de coincidencias deben apuntar a documentos, no a colecciones. Una declaración de coincidencia puede apuntar a un documento específico, como en match /cities/SF
o usar comodines para apuntar a cualquier documento en la ruta especificada, como en match /cities/{city}
.
En el ejemplo anterior, la declaración de coincidencia utiliza la sintaxis comodín {city}
. Esto significa que la regla se aplica a cualquier documento de la colección cities
, como /cities/SF
o /cities/NYC
. Cuando se evalúan las expresiones allow
en la declaración de coincidencia, la variable city
se resolverá en el nombre del documento de la ciudad, como SF
o NYC
.
Operaciones granulares
En algunas situaciones, resulta útil dividir read
y write
en operaciones más granulares. Por ejemplo, es posible que su aplicación quiera imponer condiciones diferentes en la creación de documentos y en la eliminación de documentos. O quizás desee permitir lecturas de un solo documento pero rechazar consultas grandes.
Una regla read
se puede dividir en get
y list
, mientras que una regla de write
se puede dividir en create
, update
y 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>;
}
}
}
Datos jerárquicos
Los datos en Cloud Firestore están organizados en colecciones de documentos y cada documento puede ampliar la jerarquía a través de subcolecciones. Es importante comprender cómo interactúan las reglas de seguridad con los datos jerárquicos.
Considere la situación en la que cada documento de la colección cities
contiene una subcolección landmarks
. Las reglas de seguridad se aplican solo en la ruta coincidente, por lo que los controles de acceso definidos en la colección cities
no se aplican a la subcolección de landmarks
. En su lugar, escriba reglas explícitas para controlar el acceso a las subcolecciones:
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>;
}
}
}
}
Al anidar declaraciones match
, la ruta de la declaración match
interna siempre es relativa a la ruta de la declaración match
externa. Por tanto, los siguientes conjuntos de reglas son 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>;
}
}
}
comodines recursivos
Si desea que las reglas se apliquen a una jerarquía arbitrariamente profunda, utilice la sintaxis comodín recursiva, {name=**}
. Por ejemplo:
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>;
}
}
}
Cuando se utiliza la sintaxis recursiva de comodín, la variable comodín contendrá todo el segmento de ruta coincidente, incluso si el documento está ubicado en una subcolección profundamente anidada. Por ejemplo, las reglas enumeradas anteriormente coincidirían con un documento ubicado en /cities/SF/landmarks/coit_tower
y el valor de la variable document
sería SF/landmarks/coit_tower
.
Sin embargo, tenga en cuenta que el comportamiento de los comodines recursivos depende de la versión de las reglas.
Versión 1
Las reglas de seguridad utilizan la versión 1 de forma predeterminada. En la versión 1, los comodines recursivos coinciden con uno o más elementos de ruta. No coinciden con una ruta vacía, por lo que match /cities/{city}/{document=**}
coincide con documentos en subcolecciones pero no en la colección cities
, mientras que match /cities/{document=**}
coincide con ambos documentos en la Colección y subcolecciones cities
.
Los comodines recursivos deben aparecer al final de una declaración de coincidencia.
Versión 2
En la versión 2 de las reglas de seguridad, los comodines recursivos coinciden con cero o más elementos de ruta. match/cities/{city}/{document=**}
busca documentos en cualquier subcolección, así como documentos en la colección cities
.
Debes optar por la versión 2 agregando rules_version = '2';
en la parte superior de sus reglas de seguridad:
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>;
}
}
}
Puede tener como máximo un comodín recursivo por declaración de coincidencia, pero en la versión 2, puede colocar este comodín en cualquier parte de la declaración de coincidencia. Por ejemplo:
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>;
}
}
}
Si utiliza consultas de grupos de recopilación , debe utilizar la versión 2; consulte Cómo proteger consultas de grupos de recopilación .
Declaraciones de coincidencias superpuestas
Es posible que un documento coincida con más de una declaración match
. En el caso de que varias expresiones allow
coincidan con una solicitud, se permite el acceso si alguna de las condiciones es 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;
}
}
}
En el ejemplo anterior, se permitirán todas las lecturas y escrituras en la colección cities
porque la segunda regla siempre es true
, aunque la primera regla siempre es false
.
Límites de las reglas de seguridad
Al trabajar con reglas de seguridad, tenga en cuenta los siguientes límites:
Límite | Detalles |
---|---|
Número máximo de llamadas exists() , get() y getAfter() por solicitud |
Exceder cualquiera de los límites da como resultado un error de permiso denegado. Algunas llamadas de acceso a documentos pueden almacenarse en caché y las llamadas en caché no cuentan para los límites. |
Profundidad máxima de declaración match anidada | 10 |
Longitud máxima de ruta, en segmentos de ruta, permitida dentro de un conjunto de declaraciones match anidadas | 100 |
Número máximo de variables de captura de ruta permitidas dentro de un conjunto de declaraciones match anidadas | 20 |
Profundidad máxima de llamada de función | 20 |
Número máximo de argumentos de función | 7 |
Número máximo de enlaces de variables let por función | 10 |
Número máximo de llamadas a funciones recursivas o cíclicas | 0 (no permitido) |
Número máximo de expresiones evaluadas por solicitud | 1.000 |
Tamaño máximo de un conjunto de reglas | Los conjuntos de reglas deben obedecer dos límites de tamaño:
|
Próximos pasos
- Escriba condiciones de reglas de seguridad personalizadas .
- Lea la referencia de las reglas de seguridad .