Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Lenguaje de reglas de seguridad

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Las reglas de seguridad de Firebase aprovechan lenguajes flexibles, potentes y personalizados que admiten una amplia gama de complejidad y granularidad. Puede hacer que sus Reglas sean tan específicas o tan generales como tenga sentido para su aplicación. Las reglas de Realtime Database usan una sintaxis que se parece a JavaScript en una estructura JSON. Las reglas de Cloud Firestore y Cloud Storage usan un lenguaje basado en Common Expression Language (CEL) , que se basa en CEL con declaraciones de match y allow que admiten el acceso otorgado condicionalmente.

Sin embargo, debido a que estos son lenguajes personalizados, existe una curva de aprendizaje. Utilice esta guía para comprender mejor el lenguaje de las reglas a medida que profundiza en reglas más complejas.

Seleccione un producto para obtener más información sobre sus reglas.

Estructura basica

Tienda de fuego en la nube

Las reglas de seguridad de Firebase en Cloud Firestore y Cloud Storage usan la siguiente estructura y sintaxis:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

Es importante comprender los siguientes conceptos clave a medida que crea las reglas:

  • Solicitud: el método o los métodos invocados en la instrucción allow . Estos son métodos que está permitiendo ejecutar. Los métodos estándar son: get , list , create , update y delete . Los métodos prácticos de read y write permiten un amplio acceso de lectura y escritura en la base de datos o ruta de almacenamiento especificada.
  • Ruta: la base de datos o la ubicación de almacenamiento, representada como una ruta URI.
  • Regla: la instrucción allow , que incluye una condición que permite una solicitud si se evalúa como verdadera.

Cada uno de estos conceptos se describe con más detalle a continuación.

Almacenamiento en la nube

Las reglas de seguridad de Firebase en Cloud Firestore y Cloud Storage usan la siguiente estructura y sintaxis:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

Es importante comprender los siguientes conceptos clave a medida que crea las reglas:

  • Solicitud: el método o los métodos invocados en la instrucción allow . Estos son métodos que está permitiendo ejecutar. Los métodos estándar son: get , list , create , update y delete . Los métodos prácticos de read y write permiten un amplio acceso de lectura y escritura en la base de datos o ruta de almacenamiento especificada.
  • Ruta: la base de datos o la ubicación de almacenamiento, representada como una ruta URI.
  • Regla: la instrucción allow , que incluye una condición que permite una solicitud si se evalúa como verdadera.

Cada uno de estos conceptos se describe con más detalle a continuación.

Base de datos en tiempo real

En Realtime Database, las reglas de seguridad de Firebase consisten en expresiones similares a JavaScript contenidas en un documento JSON.

Utilizan la siguiente sintaxis:

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

Hay tres elementos básicos en la regla:

  • Ruta: la ubicación de la base de datos. Esto refleja la estructura JSON de su base de datos.
  • Solicitud: estos son los métodos que usa la regla para otorgar acceso. Las reglas de read y write otorgan un amplio acceso de lectura y escritura, mientras que las reglas de validate actúan como una verificación secundaria para otorgar acceso en función de los datos entrantes o existentes.
  • Condición: la condición que permite una solicitud si se evalúa como verdadera.

Construcciones de reglas

Tienda de fuego en la nube

Los elementos básicos de una regla en Cloud Firestore y Cloud Storage son los siguientes:

  • La declaración service : declara el producto de Firebase al que se aplican las reglas.
  • El bloque de match : define una ruta en la base de datos o depósito de almacenamiento al que se aplican las reglas.
  • La instrucción allow : proporciona condiciones para otorgar acceso, diferenciadas por métodos. Los métodos admitidos incluyen: get , list , create , update , delete y los métodos de conveniencia read y write .
  • Declaraciones de function opcionales: brindan la capacidad de combinar y ajustar condiciones para su uso en varias reglas.

El service contiene uno o más bloques de match con declaraciones de allow que brindan condiciones que otorgan acceso a las solicitudes. Las variables de request y resource están disponibles para su uso en condiciones de regla. El lenguaje de reglas de seguridad de Firebase también admite declaraciones de function .

Versión de sintaxis

La declaración de syntax indica la versión del lenguaje de reglas de Firebase que se usó para escribir el código fuente. La última versión del lenguaje es v2 .

rules_version = '2';
service cloud.firestore {
...
}

Si no se proporciona una declaración rules_version , sus reglas se evaluarán utilizando el motor v1 .

Servicio

La declaración service define a qué producto o servicio de Firebase se aplican sus reglas. Solo puede incluir una declaración service por archivo fuente.

Tienda de fuego en la nube

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

Almacenamiento en la nube

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

Si está definiendo reglas para Cloud Firestore y Cloud Storage mediante Firebase CLI, deberá mantenerlas en archivos separados.

Juego

Un bloque de match declara un patrón de path que se compara con la ruta de la operación solicitada (la ruta de request.path entrante). El cuerpo de la match debe tener uno o más bloques de match anidados, instrucciones de allow o declaraciones de function . La ruta en los bloques de match anidados es relativa a la ruta en el bloque de match principal.

El patrón de path es un nombre similar a un directorio que puede incluir variables o comodines. El patrón de path permite coincidencias de segmento de ruta única y segmento de ruta múltiple. Cualquier variable enlazada en una path es visible dentro del ámbito de match o cualquier ámbito anidado donde se declara la path .

Las coincidencias con un patrón de path pueden ser parciales o completas:

  • Coincidencias parciales: el patrón de path es una coincidencia de prefijo de request.path .
  • Coincidencias completas: el patrón de path coincide con la request.path completa.

Cuando se hace una coincidencia completa , se evalúan las reglas dentro del bloque. Cuando se realiza una coincidencia parcial , las reglas de match anidadas se prueban para ver si alguna path anidada completará la coincidencia.

Las reglas en cada match completa se evalúan para determinar si se permite la solicitud. Si alguna regla coincidente otorga acceso, se permite la solicitud. Si ninguna regla coincidente otorga acceso, se deniega la solicitud.

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

Como muestra el ejemplo anterior, las declaraciones de path admiten las siguientes variables:

  • Comodín de segmento único: una variable comodín se declara en una ruta envolviendo una variable entre llaves: {variable} . Se puede acceder a esta variable dentro de la declaración de match como una string .
  • Comodín recursivo: el comodín recursivo o multisegmento coincide con varios segmentos de ruta en o debajo de una ruta. Este comodín coincide con todas las rutas debajo de la ubicación en la que lo configuró. Puede declararlo agregando la cadena =** al final de su variable de segmento: {variable=**} . Se puede acceder a esta variable dentro de la declaración de match como un objeto de path .

Permitir

El bloque de match contiene una o más declaraciones de allow . Estas son sus reglas reales. Puede aplicar reglas de allow a uno o más métodos. Las condiciones en una declaración de allow deben evaluarse como verdaderas para que Cloud Firestore o Cloud Storage concedan cualquier solicitud entrante. También puede escribir declaraciones allow sin condiciones, por ejemplo, allow read . Sin embargo, si la instrucción allow no incluye una condición, siempre permite la solicitud de ese método.

Si se cumple alguna de las reglas de allow para el método, se permite la solicitud. Además, si una regla más amplia otorga acceso, las reglas otorgan acceso e ignoran cualquier regla más granular que pueda limitar el acceso.

Considere el siguiente ejemplo, donde cualquier usuario puede leer o eliminar cualquiera de sus propios archivos. Una regla más granular solo permite escrituras si el usuario que solicita la escritura es propietario del archivo y el archivo es PNG. Un usuario puede eliminar cualquier archivo en la subruta, incluso si no son PNG, porque la regla anterior lo permite.

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

Método

Cada instrucción allow incluye un método que otorga acceso a las solicitudes entrantes del mismo método.

Método Tipo de solicitud
Métodos de conveniencia
read Cualquier tipo de solicitud de lectura
write Cualquier tipo de solicitud de escritura
Métodos estándar
get Solicitudes de lectura de documentos o archivos individuales
list Leer solicitudes de consultas y cobros
create Escribir nuevos documentos o archivos
update Escribir en documentos de bases de datos existentes o actualizar metadatos de archivos
delete Borrar datos

No puede superponer métodos de lectura en el mismo bloque de match o métodos de escritura en conflicto en la misma declaración de path .

Por ejemplo, las siguientes reglas fallarían:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

Función

A medida que sus reglas de seguridad se vuelven más complejas, es posible que desee incluir conjuntos de condiciones en funciones que pueda reutilizar en su conjunto de reglas. Las reglas de seguridad admiten funciones personalizadas. La sintaxis de las funciones personalizadas es un poco como JavaScript, pero las funciones de las reglas de seguridad están escritas en un lenguaje específico del dominio que tiene algunas limitaciones importantes:

  • Las funciones pueden contener solo una sola declaración de return . No pueden contener ninguna lógica adicional. Por ejemplo, no pueden ejecutar bucles ni llamar a servicios externos.
  • Las funciones pueden acceder automáticamente a funciones y variables desde el ámbito en el que están definidas. Por ejemplo, una función definida dentro del alcance del service cloud.firestore tiene acceso a la variable de resource y funciones integradas como get() y exists() .
  • Las funciones pueden llamar a otras funciones pero no pueden repetirse. La profundidad total de la pila de llamadas está limitada a 20.
  • En la versión de reglas v2 , las funciones pueden definir variables usando la palabra clave let . Las funciones pueden tener hasta 10 enlaces let, pero deben terminar con una declaración de retorno.

Una función se define con la palabra clave function y toma cero o más argumentos. Por ejemplo, es posible que desee combinar los dos tipos de condiciones utilizadas en los ejemplos anteriores en una sola función:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

Aquí hay un ejemplo que muestra los argumentos de la función y las asignaciones let. Las declaraciones de asignación let deben estar separadas por punto y coma.

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

Observe cómo la asignación isAdmin impone una búsqueda de la colección de administradores. Para una evaluación perezosa sin requerir búsquedas innecesarias, aproveche la naturaleza de cortocircuito de && (AND) y || (OR) comparaciones para llamar a una segunda función solo si se muestra que isAuthor es verdadero (para comparaciones && ) o falso (para comparaciones || ).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

El uso de funciones en sus reglas de seguridad las hace más fáciles de mantener a medida que crece la complejidad de sus reglas.

Almacenamiento en la nube

Los elementos básicos de una regla en Cloud Firestore y Cloud Storage son los siguientes:

  • La declaración service : declara el producto de Firebase al que se aplican las reglas.
  • El bloque de match : define una ruta en la base de datos o depósito de almacenamiento al que se aplican las reglas.
  • La instrucción allow : proporciona condiciones para otorgar acceso, diferenciadas por métodos. Los métodos admitidos incluyen: get , list , create , update , delete y los métodos de conveniencia read y write .
  • Declaraciones de function opcionales: brindan la capacidad de combinar y ajustar condiciones para su uso en varias reglas.

El service contiene uno o más bloques de match con declaraciones de allow que brindan condiciones que otorgan acceso a las solicitudes. Las variables de request y resource están disponibles para su uso en condiciones de regla. El lenguaje de reglas de seguridad de Firebase también admite declaraciones de function .

Versión de sintaxis

La declaración de syntax indica la versión del lenguaje de reglas de Firebase que se usó para escribir el código fuente. La última versión del lenguaje es v2 .

rules_version = '2';
service cloud.firestore {
...
}

Si no se proporciona una declaración rules_version , sus reglas se evaluarán utilizando el motor v1 .

Servicio

La declaración service define a qué producto o servicio de Firebase se aplican sus reglas. Solo puede incluir una declaración service por archivo fuente.

Tienda de fuego en la nube

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

Almacenamiento en la nube

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

Si está definiendo reglas para Cloud Firestore y Cloud Storage mediante Firebase CLI, deberá mantenerlas en archivos separados.

Juego

Un bloque de match declara un patrón de path que se compara con la ruta de la operación solicitada (la ruta de request.path entrante). El cuerpo de la match debe tener uno o más bloques de match anidados, instrucciones de allow o declaraciones de function . La ruta en los bloques de match anidados es relativa a la ruta en el bloque de match principal.

El patrón de path es un nombre similar a un directorio que puede incluir variables o comodines. El patrón de path permite coincidencias de segmento de ruta única y segmento de ruta múltiple. Cualquier variable enlazada en una path es visible dentro del ámbito de match o cualquier ámbito anidado donde se declara la path .

Las coincidencias con un patrón de path pueden ser parciales o completas:

  • Coincidencias parciales: el patrón de path es una coincidencia de prefijo de request.path .
  • Coincidencias completas: el patrón de path coincide con la request.path completa.

Cuando se hace una coincidencia completa , se evalúan las reglas dentro del bloque. Cuando se realiza una coincidencia parcial , las reglas de match anidadas se prueban para ver si alguna path anidada completará la coincidencia.

Las reglas en cada match completa se evalúan para determinar si se permite la solicitud. Si alguna regla coincidente otorga acceso, se permite la solicitud. Si ninguna regla coincidente otorga acceso, se deniega la solicitud.

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

Como muestra el ejemplo anterior, las declaraciones de path admiten las siguientes variables:

  • Comodín de segmento único: una variable comodín se declara en una ruta envolviendo una variable entre llaves: {variable} . Se puede acceder a esta variable dentro de la declaración de match como una string .
  • Comodín recursivo: el comodín recursivo o multisegmento coincide con varios segmentos de ruta en o debajo de una ruta. Este comodín coincide con todas las rutas debajo de la ubicación en la que lo configuró. Puede declararlo agregando la cadena =** al final de su variable de segmento: {variable=**} . Se puede acceder a esta variable dentro de la declaración de match como un objeto de path .

Permitir

El bloque de match contiene una o más declaraciones de allow . Estas son sus reglas reales. Puede aplicar reglas de allow a uno o más métodos. Las condiciones en una declaración de allow deben evaluarse como verdaderas para que Cloud Firestore o Cloud Storage concedan cualquier solicitud entrante. También puede escribir declaraciones allow sin condiciones, por ejemplo, allow read . Sin embargo, si la instrucción allow no incluye una condición, siempre permite la solicitud de ese método.

Si se cumple alguna de las reglas de allow para el método, se permite la solicitud. Además, si una regla más amplia otorga acceso, las reglas otorgan acceso e ignoran cualquier regla más granular que pueda limitar el acceso.

Considere el siguiente ejemplo, donde cualquier usuario puede leer o eliminar cualquiera de sus propios archivos. Una regla más granular solo permite escrituras si el usuario que solicita la escritura es propietario del archivo y el archivo es PNG. Un usuario puede eliminar cualquier archivo en la subruta, incluso si no son PNG, porque la regla anterior lo permite.

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

Método

Cada instrucción allow incluye un método que otorga acceso a las solicitudes entrantes del mismo método.

Método Tipo de solicitud
Métodos de conveniencia
read Cualquier tipo de solicitud de lectura
write Cualquier tipo de solicitud de escritura
Métodos estándar
get Solicitudes de lectura de documentos o archivos individuales
list Leer solicitudes de consultas y cobros
create Escribir nuevos documentos o archivos
update Escribir en documentos de bases de datos existentes o actualizar metadatos de archivos
delete Borrar datos

No puede superponer métodos de lectura en el mismo bloque de match o métodos de escritura en conflicto en la misma declaración de path .

Por ejemplo, las siguientes reglas fallarían:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

Función

A medida que sus reglas de seguridad se vuelven más complejas, es posible que desee incluir conjuntos de condiciones en funciones que pueda reutilizar en su conjunto de reglas. Las reglas de seguridad admiten funciones personalizadas. La sintaxis de las funciones personalizadas es un poco como JavaScript, pero las funciones de las reglas de seguridad están escritas en un lenguaje específico del dominio que tiene algunas limitaciones importantes:

  • Las funciones pueden contener solo una sola declaración de return . No pueden contener ninguna lógica adicional. Por ejemplo, no pueden ejecutar bucles ni llamar a servicios externos.
  • Las funciones pueden acceder automáticamente a funciones y variables desde el ámbito en el que están definidas. Por ejemplo, una función definida dentro del alcance del service cloud.firestore tiene acceso a la variable de resource y funciones integradas como get() y exists() .
  • Las funciones pueden llamar a otras funciones pero no pueden repetirse. La profundidad total de la pila de llamadas está limitada a 20.
  • En la versión de reglas v2 , las funciones pueden definir variables usando la palabra clave let . Las funciones pueden tener hasta 10 enlaces let, pero deben terminar con una declaración de retorno.

Una función se define con la palabra clave function y toma cero o más argumentos. Por ejemplo, es posible que desee combinar los dos tipos de condiciones utilizadas en los ejemplos anteriores en una sola función:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

Aquí hay un ejemplo que muestra los argumentos de la función y las asignaciones let. Las declaraciones de asignación let deben estar separadas por punto y coma.

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

Observe cómo la asignación isAdmin impone una búsqueda de la colección de administradores. Para una evaluación perezosa sin requerir búsquedas innecesarias, aproveche la naturaleza de cortocircuito de && (AND) y || (OR) comparaciones para llamar a una segunda función solo si se muestra que isAuthor es verdadero (para comparaciones && ) o falso (para comparaciones || ).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

El uso de funciones en sus reglas de seguridad las hace más fáciles de mantener a medida que crece la complejidad de sus reglas.

Base de datos en tiempo real

Como se describió anteriormente, las reglas de la base de datos en tiempo real incluyen tres elementos básicos: la ubicación de la base de datos como espejo de la estructura JSON de la base de datos, el tipo de solicitud y la condición que otorga el acceso.

Ubicación de la base de datos

La estructura de sus reglas debe seguir la estructura de los datos que ha almacenado en su base de datos. Por ejemplo, en una aplicación de chat con una lista de mensajes, es posible que tenga datos como estos:

  {
    "messages": {
      "message0": {
        "content": "Hello",
        "timestamp": 1405704370369
      },
      "message1": {
        "content": "Goodbye",
        "timestamp": 1405704395231
      },
      ...
    }
  }

Sus reglas deben reflejar esa estructura. Por ejemplo:

  {
    "rules": {
      "messages": {
        "$message": {
          // only messages from the last ten minutes can be read
          ".read": "data.child('timestamp').val() > (now - 600000)",

          // new messages must have a string content and a number timestamp
          ".validate": "newData.hasChildren(['content', 'timestamp']) &&
                        newData.child('content').isString() &&
                        newData.child('timestamp').isNumber()"
        }
      }
    }
  }

Como muestra el ejemplo anterior, las reglas de la base de datos en tiempo real admiten una variable de $location para hacer coincidir los segmentos de la ruta. Use el prefijo $ delante de su segmento de ruta para hacer coincidir su regla con cualquier nodo secundario a lo largo de la ruta.

  {
    "rules": {
      "rooms": {
        // This rule applies to any child of /rooms/, the key for each room id
        // is stored inside $room_id variable for reference
        "$room_id": {
          "topic": {
            // The room's topic can be changed if the room id has "public" in it
            ".write": "$room_id.contains('public')"
          }
        }
      }
    }
  }

También puede usar la $variable en paralelo con nombres de rutas constantes.

  {
    "rules": {
      "widget": {
        // a widget can have a title or color attribute
        "title": { ".validate": true },
        "color": { ".validate": true },

        // but no other child paths are allowed
        // in this case, $other means any key excluding "title" and "color"
        "$other": { ".validate": false }
      }
    }
  }

Método

En Realtime Database, hay tres tipos de reglas. Dos de estos tipos de reglas ( read y write ) se aplican al método de una solicitud entrante. El tipo de regla de validate aplica estructuras de datos y valida el formato y el contenido de los datos. Las reglas ejecutan reglas .validate después de verificar que una regla .write otorga acceso.

Tipos de reglas
.leer Describe si los usuarios pueden leer los datos y cuándo.
.escribe Describe si se permite escribir datos y cuándo.
.validar Define el aspecto que tendrá un valor con el formato correcto, si tiene atributos secundarios y el tipo de datos.

De forma predeterminada, si no hay una regla que lo permita, se deniega el acceso a una ruta.

Condiciones de construcción

Tienda de fuego en la nube

Una condición es una expresión booleana que determina si se debe permitir o denegar una operación en particular. Las variables de request y resource proporcionan contexto para esas condiciones.

La variable de request

La variable de request incluye los siguientes campos y la información correspondiente:

request.auth

Un token web JSON (JWT) que contiene credenciales de autenticación de Firebase Authentication. El token de auth contiene un conjunto de reclamos estándar y cualquier reclamo personalizado que cree a través de Firebase Authentication. Obtén más información sobre las reglas de seguridad y la autenticación de Firebase .

request.method

El request.method puede ser cualquiera de los métodos estándar o un método personalizado. Los métodos de conveniencia de read y write también existen para simplificar las reglas de escritura que se aplican a todos los métodos estándar de solo lectura o de solo escritura, respectivamente.

request.params

Los request.params incluyen cualquier dato no relacionado específicamente con el request.resource que podría ser útil para la evaluación. En la práctica, este mapa debe estar vacío para todos los métodos estándar y debe contener datos que no sean de recursos para los métodos personalizados. Los servicios deben tener cuidado de no cambiar el nombre o modificar el tipo de cualquiera de las claves y valores presentados como parámetros.

request.path

request.path es la ruta del resource de destino. La ruta es relativa al servicio. Los segmentos de ruta que contienen caracteres seguros que no son URL, como / , están codificados como URL.

La variable del resource

El resource es el valor actual dentro del servicio representado como un mapa de pares clave-valor. Hacer referencia a un resource dentro de una condición dará como resultado, como máximo, una lectura del valor del servicio. Esta búsqueda contará contra cualquier cuota relacionada con el servicio para el recurso. Para las solicitudes de get , el resource solo contará para la cuota en caso de denegación.

Operadores y precedencia de operadores

Utilice la siguiente tabla como referencia para los operadores y su precedencia correspondiente en Reglas para Cloud Firestore y Cloud Storage.

Dadas las expresiones arbitrarias a y b , un campo f y un índice i .

Operador Descripción Asociatividad
a[i] a() af Índice, llamada, acceso al campo de izquierda a derecha
!a -a negación unaria De derecha a izquierda
a/ba%ba*b Operadores multiplicativos de izquierda a derecha
a+b ab Operadores aditivos de izquierda a derecha
a>ba>=ba Operadores relacionales de izquierda a derecha
a in b Existencia en lista o mapa de izquierda a derecha
a is type Comparación de tipos, donde el type puede ser bool, int, float, number, string, list, map, timestamp, duration, path o latlng de izquierda a derecha
a==ba!=b Operadores de comparación de izquierda a derecha
a && b Y condicional de izquierda a derecha
a || b O condicional de izquierda a derecha
a ? true_value : false_value expresión ternaria de izquierda a derecha

Almacenamiento en la nube

Una condición es una expresión booleana que determina si se debe permitir o denegar una operación en particular. Las variables de request y resource proporcionan contexto para esas condiciones.

La variable de request

La variable de request incluye los siguientes campos y la información correspondiente:

request.auth

Un token web JSON (JWT) que contiene credenciales de autenticación de Firebase Authentication. El token de auth contiene un conjunto de reclamos estándar y cualquier reclamo personalizado que cree a través de Firebase Authentication. Obtén más información sobre las reglas de seguridad y la autenticación de Firebase .

request.method

El request.method puede ser cualquiera de los métodos estándar o un método personalizado. Los métodos de conveniencia de read y write también existen para simplificar las reglas de escritura que se aplican a todos los métodos estándar de solo lectura o de solo escritura, respectivamente.

request.params

Los request.params incluyen cualquier dato no relacionado específicamente con el request.resource que podría ser útil para la evaluación. En la práctica, este mapa debe estar vacío para todos los métodos estándar y debe contener datos que no sean de recursos para los métodos personalizados. Los servicios deben tener cuidado de no cambiar el nombre o modificar el tipo de cualquiera de las claves y valores presentados como parámetros.

request.path

request.path es la ruta del resource de destino. La ruta es relativa al servicio. Los segmentos de ruta que contienen caracteres seguros que no son URL, como / , están codificados como URL.

La variable del resource

El resource es el valor actual dentro del servicio representado como un mapa de pares clave-valor. Hacer referencia a un resource dentro de una condición dará como resultado, como máximo, una lectura del valor del servicio. Esta búsqueda contará contra cualquier cuota relacionada con el servicio para el recurso. Para las solicitudes de get , el resource solo contará para la cuota en caso de denegación.

Operadores y precedencia de operadores

Utilice la siguiente tabla como referencia para los operadores y su precedencia correspondiente en Reglas para Cloud Firestore y Cloud Storage.

Dadas las expresiones arbitrarias a y b , un campo f y un índice i .

Operador Descripción Asociatividad
a[i] a() af Índice, llamada, acceso al campo de izquierda a derecha
!a -a negación unaria De derecha a izquierda
a/ba%ba*b Operadores multiplicativos de izquierda a derecha
a+b ab Operadores aditivos de izquierda a derecha
a>ba>=ba Operadores relacionales de izquierda a derecha
a in b Existencia en lista o mapa de izquierda a derecha
a is type Comparación de tipos, donde el type puede ser bool, int, float, number, string, list, map, timestamp, duration, path o latlng de izquierda a derecha
a==ba!=b Operadores de comparación de izquierda a derecha
a && b Y condicional de izquierda a derecha
a || b O condicional de izquierda a derecha
a ? true_value : false_value expresión ternaria de izquierda a derecha

Base de datos en tiempo real

Una condición es una expresión booleana que determina si se debe permitir o denegar una operación en particular. Puede definir esas condiciones en las reglas de la base de datos en tiempo real de las siguientes maneras.

Variables predefinidas

Hay una serie de variables predefinidas útiles a las que se puede acceder dentro de una definición de regla. Aquí hay un breve resumen de cada uno:

Variables predefinidas
ahora La hora actual en milisegundos desde la época de Linux. Esto funciona especialmente bien para validar marcas de tiempo creadas con firebase.database.ServerValue.TIMESTAMP del SDK.
raíz Una RuleDataSnapshot que representa la ruta raíz en la base de datos de Firebase tal como existe antes del intento de operación.
nuevos datos Una RuleDataSnapshot que representa los datos tal como existirían después del intento de operación. Incluye los nuevos datos que se están escribiendo y los datos existentes.
datos Una RuleDataSnapshot que representa los datos tal como existían antes del intento de operación.
$ variables Una ruta comodín utilizada para representar ID y claves secundarias dinámicas.
autenticación Representa la carga útil del token de un usuario autenticado.

Estas variables se pueden utilizar en cualquier parte de sus reglas. Por ejemplo, las siguientes reglas de seguridad garantizan que los datos escritos en el nodo /foo/ deben ser una cadena de menos de 100 caracteres:

{
  "rules": {
    "foo": {
      // /foo is readable by the world
      ".read": true,

      // /foo is writable by the world
      ".write": true,

      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}

Reglas basadas en datos

Cualquier dato en su base de datos se puede usar en sus reglas. Usando las variables predefinidas root , data y newData , puede acceder a cualquier ruta tal como existiría antes o después de un evento de escritura.

Considere este ejemplo, que permite operaciones de escritura siempre que el valor del nodo /allow_writes/ sea true , el nodo principal no tenga un indicador de readOnly establecido y haya un elemento secundario llamado foo en los datos recién escritos:

".write": "root.child('allow_writes').val() === true &&
          !data.parent().child('readOnly').exists() &&
          newData.child('foo').exists()"

Reglas basadas en consultas

Aunque no puede usar reglas como filtros, puede limitar el acceso a subconjuntos de datos usando parámetros de consulta en sus reglas. Usar query. expresiones en sus reglas para otorgar acceso de lectura o escritura en función de los parámetros de consulta.

Por ejemplo, la siguiente regla basada en consultas utiliza reglas de seguridad basadas en usuarios y reglas basadas en consultas para restringir el acceso a los datos en la colección de baskets solo a las cestas de la compra que posee el usuario activo:

"baskets": {
  ".read": "auth.uid !== null &&
            query.orderByChild === 'owner' &&
            query.equalTo === auth.uid" // restrict basket access to owner of basket
}

La siguiente consulta, que incluye los parámetros de consulta en la regla, se realizará correctamente:

db.ref("baskets").orderByChild("owner")
                 .equalTo(auth.currentUser.uid)
                 .on("value", cb)                 // Would succeed

Sin embargo, las consultas que no incluyen los parámetros en la regla fallarán con un error PermissionDenied denegado:

db.ref("baskets").on("value", cb)                 // Would fail with PermissionDenied

También puede usar reglas basadas en consultas para limitar la cantidad de datos que descarga un cliente a través de operaciones de lectura.

Por ejemplo, la siguiente regla limita el acceso de lectura solo a los primeros 1000 resultados de una consulta, ordenados por prioridad:

messages: {
  ".read": "query.orderByKey &&
            query.limitToFirst <= 1000"
}

// Example queries:

db.ref("messages").on("value", cb)                // Would fail with PermissionDenied

db.ref("messages").limitToFirst(1000)
                  .on("value", cb)                // Would succeed (default order by key)

La siguiente query. Las expresiones están disponibles en Reglas de base de datos en tiempo real.

Expresiones de regla basadas en consultas
Expresión Escribe Descripción
consulta.orderByKey
consulta.orderByPriority
consulta.orderByValue
booleano True para consultas ordenadas por clave, prioridad o valor. Falso en caso contrario.
consulta.orderByChild cuerda
nulo
Utilice una cadena para representar la ruta relativa a un nodo secundario. Por ejemplo, query.orderByChild === "address/zip" . Si la consulta no está ordenada por un nodo secundario, este valor es nulo.
consulta.startAt
consulta.endAt
consulta.igual a
cuerda
número
booleano
nulo
Recupera los límites de la consulta en ejecución o devuelve un valor nulo si no hay un conjunto de límites.
consulta.limitToFirst
consulta.limitToLast
número
nulo
Recupera el límite de la consulta en ejecución o devuelve un valor nulo si no hay un límite establecido.

Operadores

Las reglas de la base de datos en tiempo real admiten una serie de operadores que puede usar para combinar variables en la declaración de condición. Consulte la lista completa de operadores en la documentación de referencia .

Creando condiciones

Sus condiciones reales variarán según el acceso que desee otorgar. Las reglas ofrecen intencionalmente un enorme grado de flexibilidad, por lo que, en última instancia, las reglas de su aplicación pueden ser tan simples o tan complejas como las necesite.

Para obtener orientación sobre la creación de reglas simples listas para producción, consulte Reglas de seguridad básicas .