Ir a la consola

Lenguaje de las reglas de seguridad

Las reglas de seguridad de Firebase aprovechan los lenguajes flexibles, poderosos y personalizados que admiten un rango amplio de complejidad y nivel de detalle. Puedes hacer que tus reglas sean específicas o generales para que se adapten a tu app. Las reglas de Realtime Database usan una sintaxis similar a la de JavaScript en una estructura JSON. Las reglas de Cloud Firestore y Cloud Storage usan un lenguaje que se basa en Common Expression Language (CEL), que se compila en CEL con las declaraciones matchallow que admiten otorgar acceso de forma condicional.

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

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

Estructura básica

Cloud Firestore

Las reglas de seguridad de Firebase en Cloud Firestore y Storage utilizan 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 compilas las reglas:

  • Solicitud: Es el método, o los métodos, invocados en la declaración allow que permites que se ejecuten. Los métodos estándar son: get, list, create, update y delete. Los métodos recomendados read y write habilitan un acceso amplio de lectura y escritura en la ruta de acceso especificada de la base de datos o el almacenamiento.
  • Ruta de acceso: Es la ubicación de la base de datos o del almacenamiento, representada como una ruta URI.
  • Regla: Es la declaració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.

Cloud Storage

Las reglas de seguridad de Firebase en Cloud Firestore y Storage utilizan 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 compilas las reglas:

  • Solicitud: Es el método, o los métodos, invocados en la declaración allow que permites que se ejecuten. Los métodos estándar son: get, list, create, update y delete. Los métodos recomendados read y write habilitan un acceso amplio de lectura y escritura en la ruta de acceso especificada de la base de datos o el almacenamiento.
  • Ruta de acceso: Es la ubicación de la base de datos o del almacenamiento, representada como una ruta URI.
  • Regla: Es la declaració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.

Realtime Database

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

Usan 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 duplica la estructura JSON de tu base de datos.
  • Solicitud: Estos son los métodos que usa la regla para otorgar acceso. Las reglas read y write otorgan un amplio acceso de lectura y escritura, mientras que las reglas validate actúan como una verificación secundaria para otorgar acceso en función de los datos entrantes o existentes.
  • Condición: Es la condición que permite una solicitud si se evalúa como verdadera.

Construcciones de las reglas

Cloud Firestore

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

  • La declaración service: Declara a qué producto de Firebase se aplican las reglas.
  • El bloque match: Define a qué ruta de acceso, en la base de datos o en el depósito de almacenamiento, se aplican las reglas.
  • La declaración allow: Proporciona condiciones para otorgar el acceso, diferenciadas por métodos. Los métodos admitidos incluyen los siguientes: get, list, create, update, delete y los métodos recomendados readwrite.
  • Declaraciones opcionales function: Proporcionan la capacidad de combinar y unir condiciones para su uso en varias reglas.

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

Service

En la declaración service se define a qué producto o servicio de Firebase se aplican tus reglas. Puedes incluir solo una declaración service por archivo de origen.

Cloud Firestore

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

Storage

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

Si defines reglas para Cloud Firestore y Storage mediante Firebase CLI, tendrás que mantenerlas en archivos separados.

Match

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

El patrón path es un nombre similar a un directorio que puede incluir variables o comodines. El patrón path permite que coincidan segmentos con ruta única o con varias rutas. Todas las variables enlazadas en un patrón path son visibles dentro del alcance match o cualquier alcance anidado en el que se declare path.

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

  • Coincidencias parciales: El patrón path es una coincidencia de prefijo de request.path.
  • Coincidencias completas: El patrón path coincide con request.path por completo.

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

Las reglas en cada match completo se evalúan para determinar si se debe permitir la solicitud. Si cualquier 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 path admiten las siguientes variables:

  • Comodín en segmento único: Una variable de comodín se declara en una ruta de acceso mediante la unión de una variable entre llaves: {variable}. Esta variable es accesible dentro de la declaración match como una string.
  • Comodín recurrente: El comodín recurrente, o de varios segmentos, coincide con varios segmentos de la ruta de acceso en una ruta o debajo de ella. Este comodín coincide con todas las rutas debajo de la ubicación donde lo configuraste. Puedes declararlo si agregas la string =** al final de la variable de tu segmento: {variable=**}. Esta variable es accesible dentro de la declaración match como un objeto path.

Allow

El bloque match contiene una o más declaraciones allow. Estas son tus reglas reales. Puedes aplicar reglas allow a uno o más métodos. Las condiciones en una declaración allow se deben evaluar como verdaderas en Cloud Firestore o Storage a fin de otorgar las solicitudes entrantes. También puedes escribir declaraciones allow sin condiciones, por ejemplo, allow read. Sin embargo, si la declaración allow no incluye una condición, siempre permitirá la solicitud de ese método.

Si cualquiera de las reglas allow para el método están satisfechas, se permite la solicitud. Además, si una regla más amplia otorga acceso, las reglas lo otorgan y, además, ignoran cualquier otra regla detallada que pueda limitar el acceso.

Considera el siguiente ejemplo, en el que cualquier usuario puede leer o borrar cualquiera de sus propios archivos. Una regla más detallada solo permite operaciones de escritura si el usuario que la solicita es propietario del archivo y el archivo es un PNG. Un usuario puede borrar cualquier archivo en la ruta secundaria, 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.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.uid == userId && imageId.matches('*.png');
  }
}

Método

Cada declaración allow incluye un método que permite el acceso a las solicitudes entrantes del mismo método.

Método Tipo de solicitud
Métodos recomendados
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 Solicitudes de lectura para búsquedas y colecciones
create Escribir documentos o archivos nuevos
update Escribir en documentos o archivos existentes
delete Borrar datos

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

Por ejemplo, las siguientes reglas fallarían:

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

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if 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.uid == "me";
    }
  }
}

Función

A medida que tus reglas de seguridad se vuelvan más complejas, te recomendamos agrupar conjuntos de condiciones en funciones que puedas volver a usar en tu conjunto de reglas. Las reglas de seguridad admiten funciones personalizadas. La sintaxis de las funciones personalizadas es similar a la de JavaScript, pero las funciones de reglas de seguridad se escriben en un lenguaje específico del dominio y tiene algunas limitaciones importantes:

  • Las funciones solo pueden incluir una única declaración return. No pueden contener lógica adicional. Por ejemplo, no pueden crear variables intermedias, ejecutar bucles ni llamar a servicios externos.
  • Las funciones pueden acceder automáticamente a funciones y variables desde el alcance en el que se definen. Por ejemplo, una función definida dentro del alcance service cloud.firestore tiene acceso a la variable resource y a las funciones integradas, como get() y exists().
  • Las funciones pueden llamar a otras funciones, pero no hacen referencia a sí mismas. La profundidad total de la pila de llamadas se limita a 20.

Una función se define con la palabra clave function y usa cero o más argumentos. Por ejemplo, puedes combinar los dos tipos de condiciones usados en los ejemplos anteriores en una única 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();
    }
  }
}

Usar funciones en las reglas de seguridad facilita su mantenimiento a medida que aumenta su complejidad.

Cloud Storage

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

  • La declaración service: Declara a qué producto de Firebase se aplican las reglas.
  • El bloque match: Define a qué ruta de acceso, en la base de datos o en el depósito de almacenamiento, se aplican las reglas.
  • La declaración allow: Proporciona condiciones para otorgar el acceso, diferenciadas por métodos. Los métodos admitidos incluyen los siguientes: get, list, create, update, delete y los métodos recomendados readwrite.
  • Declaraciones opcionales function: Proporcionan la capacidad de combinar y unir condiciones para su uso en varias reglas.

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

Service

En la declaración service se define a qué producto o servicio de Firebase se aplican tus reglas. Puedes incluir solo una declaración service por archivo de origen.

Cloud Firestore

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

Storage

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

Si defines reglas para Cloud Firestore y Storage mediante Firebase CLI, tendrás que mantenerlas en archivos separados.

Match

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

El patrón path es un nombre similar a un directorio que puede incluir variables o comodines. El patrón path permite que coincidan segmentos con ruta única o con varias rutas. Todas las variables enlazadas en un patrón path son visibles dentro del alcance match o cualquier alcance anidado en el que se declare path.

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

  • Coincidencias parciales: El patrón path es una coincidencia de prefijo de request.path.
  • Coincidencias completas: El patrón path coincide con request.path por completo.

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

Las reglas en cada match completo se evalúan para determinar si se debe permitir la solicitud. Si cualquier 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 path admiten las siguientes variables:

  • Comodín en segmento único: Una variable de comodín se declara en una ruta de acceso mediante la unión de una variable entre llaves: {variable}. Esta variable es accesible dentro de la declaración match como una string.
  • Comodín recurrente: El comodín recurrente, o de varios segmentos, coincide con varios segmentos de la ruta de acceso en una ruta o debajo de ella. Este comodín coincide con todas las rutas debajo de la ubicación donde lo configuraste. Puedes declararlo si agregas la string =** al final de la variable de tu segmento: {variable=**}. Esta variable es accesible dentro de la declaración match como un objeto path.

Allow

El bloque match contiene una o más declaraciones allow. Estas son tus reglas reales. Puedes aplicar reglas allow a uno o más métodos. Las condiciones en una declaración allow se deben evaluar como verdaderas en Cloud Firestore o Storage a fin de otorgar las solicitudes entrantes. También puedes escribir declaraciones allow sin condiciones, por ejemplo, allow read. Sin embargo, si la declaración allow no incluye una condición, siempre permitirá la solicitud de ese método.

Si cualquiera de las reglas allow para el método están satisfechas, se permite la solicitud. Además, si una regla más amplia otorga acceso, las reglas lo otorgan y, además, ignoran cualquier otra regla detallada que pueda limitar el acceso.

Considera el siguiente ejemplo, en el que cualquier usuario puede leer o borrar cualquiera de sus propios archivos. Una regla más detallada solo permite operaciones de escritura si el usuario que la solicita es propietario del archivo y el archivo es un PNG. Un usuario puede borrar cualquier archivo en la ruta secundaria, 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.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.uid == userId && imageId.matches('*.png');
  }
}

Método

Cada declaración allow incluye un método que permite el acceso a las solicitudes entrantes del mismo método.

Método Tipo de solicitud
Métodos recomendados
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 Solicitudes de lectura para búsquedas y colecciones
create Escribir documentos o archivos nuevos
update Escribir en documentos o archivos existentes
delete Borrar datos

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

Por ejemplo, las siguientes reglas fallarían:

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

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if 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.uid == "me";
    }
  }
}

Función

A medida que tus reglas de seguridad se vuelvan más complejas, te recomendamos agrupar conjuntos de condiciones en funciones que puedas volver a usar en tu conjunto de reglas. Las reglas de seguridad admiten funciones personalizadas. La sintaxis de las funciones personalizadas es similar a la de JavaScript, pero las funciones de reglas de seguridad se escriben en un lenguaje específico del dominio y tiene algunas limitaciones importantes:

  • Las funciones solo pueden incluir una única declaración return. No pueden contener lógica adicional. Por ejemplo, no pueden crear variables intermedias, ejecutar bucles ni llamar a servicios externos.
  • Las funciones pueden acceder automáticamente a funciones y variables desde el alcance en el que se definen. Por ejemplo, una función definida dentro del alcance service cloud.firestore tiene acceso a la variable resource y a las funciones integradas, como get() y exists().
  • Las funciones pueden llamar a otras funciones, pero no hacen referencia a sí mismas. La profundidad total de la pila de llamadas se limita a 20.

Una función se define con la palabra clave function y usa cero o más argumentos. Por ejemplo, puedes combinar los dos tipos de condiciones usados en los ejemplos anteriores en una única 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();
    }
  }
}

Usar funciones en las reglas de seguridad facilita su mantenimiento a medida que aumenta su complejidad.

Realtime Database

Como se describió anteriormente, las reglas de Realtime Database incluyen tres elementos básicos: la ubicación de la base de datos como una duplicación 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 tus reglas debe seguir la de los datos que almacenaste en tu base de datos. Por ejemplo, en una app de chat con una lista de mensajes, es posible que tengas datos que se parezcan a los siguientes:

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

Tus reglas deben duplicar 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 se muestra en el ejemplo anterior, las reglas de Realtime Database admiten una variable $location para que coincida con los segmentos de la ruta de acceso. Usa el prefijo $ delante del segmento de ruta de acceso para hacer coincidir tu regla con los nodos secundarios 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 puedes usar $variable de forma paralela con nombres de ruta de acceso 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 validate aplica estructuras de datos y valida el formato y contenido de los mismos. Las reglas ejecutan reglas .validate después de verificar que una regla .write otorga acceso.

Tipos de reglas
.read Describe si los usuarios pueden leer los datos y cuándo pueden hacerlo.
.write Indica si se permite la escritura de datos y en qué momento se permite.
.validate Define el aspecto de un valor con formato correcto, si este tiene atributos secundarios y el tipo de datos.

De acuerdo con la configuración predeterminada, si no hay una regla que lo permita, se rechaza el acceso a la ruta de acceso.

Cómo compilar condiciones

Cloud Firestore

Una condición es una expresión booleana que determina si se debe permitir o rechazar una operación en particular. Las variables requestresource proporcionan contexto para esas condiciones.

Variable request

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

request.auth

Un token web JSON (JWT), que contiene credenciales de autenticación del token auth de Firebase Authentication, contiene un conjunto de reclamaciones estándar y cualquier reclamación personalizada que creas a través de Firebase Authentication. Obtén más información sobre las reglas de seguridad y autenticación de Firebase.

request.method

El método request.method puede ser cualquiera de los métodos estándar o un método personalizado. Los métodos recomendados 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 solo escritura, respectivamente.

request.params

En el método request.params se incluyen los datos que no estén relacionados de forma específica a request.resource que puedan ser útiles para su 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 de métodos personalizados. En los servicios se debe tener cuidado de no cambiar el nombre ni modificar el tipo de cualquiera de las claves y los valores presentados como parámetros.

request.path

El método request.path es la ruta de acceso para el objetivo resource. Esta ruta es relativa al servicio. Los segmentos de ruta que contienen caracteres seguros que no son URL, como /, están codificados en URL.

Variable resource

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

Operadores y prioridad de operadores

Usa la tabla a continuación como referencia para los operadores y su prioridad correspondiente en las reglas de Cloud Firestore y Storage.

En vista de las expresiones arbitrarias ab, el campo f y el índice i.

Operador Descripción Asociatividad
a[i] a() a.f Acceso a índice, llamada o campo De izquierda a derecha
!a -a Negación unaria De derecha a izquierda
a/b a%b a*b Operadores multiplicativos De izquierda a derecha
a+b a-b Operadores aditivos De izquierda a derecha
a>b a>=b a<b a<=b Operadores relacionales De izquierda a derecha
a in b, a is b Existencia en lista o mapa, comparación de tipos De izquierda a derecha
a==b a!=b Operadores de comparación De izquierda a derecha
a && b Condicional AND De izquierda a derecha
a || b Condicional OR De izquierda a derecha

Cloud Storage

Una condición es una expresión booleana que determina si se debe permitir o rechazar una operación en particular. Las variables requestresource proporcionan contexto para esas condiciones.

Variable request

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

request.auth

Un token web JSON (JWT), que contiene credenciales de autenticación del token auth de Firebase Authentication, contiene un conjunto de reclamaciones estándar y cualquier reclamación personalizada que creas a través de Firebase Authentication. Obtén más información sobre las reglas de seguridad y autenticación de Firebase.

request.method

El método request.method puede ser cualquiera de los métodos estándar o un método personalizado. Los métodos recomendados 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 solo escritura, respectivamente.

request.params

En el método request.params se incluyen los datos que no estén relacionados de forma específica a request.resource que puedan ser útiles para su 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 de métodos personalizados. En los servicios se debe tener cuidado de no cambiar el nombre ni modificar el tipo de cualquiera de las claves y los valores presentados como parámetros.

request.path

El método request.path es la ruta de acceso para el objetivo resource. Esta ruta es relativa al servicio. Los segmentos de ruta que contienen caracteres seguros que no son URL, como /, están codificados en URL.

Variable resource

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

Operadores y prioridad de operadores

Usa la tabla a continuación como referencia para los operadores y su prioridad correspondiente en las reglas de Cloud Firestore y Storage.

En vista de las expresiones arbitrarias ab, el campo f y el índice i.

Operador Descripción Asociatividad
a[i] a() a.f Acceso a índice, llamada o campo De izquierda a derecha
!a -a Negación unaria De derecha a izquierda
a/b a%b a*b Operadores multiplicativos De izquierda a derecha
a+b a-b Operadores aditivos De izquierda a derecha
a>b a>=b a<b a<=b Operadores relacionales De izquierda a derecha
a in b, a is b Existencia en lista o mapa, comparación de tipos De izquierda a derecha
a==b a!=b Operadores de comparación De izquierda a derecha
a && b Condicional AND De izquierda a derecha
a || b Condicional OR De izquierda a derecha

Realtime Database

Una condición es una expresión booleana que determina si se debe permitir o rechazar una operación en particular. Puedes definir esas condiciones en las reglas de Realtime Database 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 reglas. A continuación, se incluye un breve resumen de cada una:

Variables predefinidas
now La hora actual en milisegundos desde el tiempo Linux. Esto funciona particularmente bien para validar marcas de tiempo creadas con firebase.database.ServerValue.TIMESTAMP del SDK.
root Una RuleDataSnapshot que representa la ruta de acceso de raíz en la base de datos de Firebase, tal como existe antes de la operación que se intenta ejecutar.
newData Una RuleDataSnapshot que representa los datos como existirían después de la operación que se intenta ejecutar. Incluye los datos nuevos que se escriben y los datos existentes.
data Una RuleDataSnapshot que representa los datos como existían antes de la operación que se intenta ejecutar.
$ variables Ruta de acceso de comodín que se usa para representar los ID y las claves secundarias dinámicas.
auth Representa la carga útil del token de un usuario autenticado.

Estas variables pueden usarse en cualquier sección de tus reglas. Por ejemplo, las reglas de seguridad que se muestran a continuación garantizan que los datos escritos en el nodo /foo/ deben ser una string con 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 tu base de datos se puede usar en tus reglas. Con el uso de las variables predefinidas root, data y newData, puedes acceder a cualquier ruta de acceso en su estado anterior o posterior a un evento de escritura.

Considera el siguiente ejemplo, que permite operaciones de escritura siempre que el valor del nodo /allow_writes/ sea true, el nodo superior no tenga establecida una marca readOnly y exista un elemento secundario llamado foo en los datos nuevos que se escriben:

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

Reglas basadas en búsquedas

Si bien no puedes usar reglas como filtros, puedes limitar el acceso a subconjuntos de datos mediante el uso de parámetros de consulta en tus reglas. Usa expresiones de query. en tus reglas para otorgar acceso de lectura o de escritura en función de los parámetros de consulta.

Por ejemplo, la siguiente regla basada en búsquedas usa reglas de seguridad basadas en usuarios y reglas basadas en búsquedas para restringir el acceso a los datos de la colección baskets únicamente a las canastas de compras que le pertenecen al 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 ejecutaría 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ían con un error de PermissionDenied:

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

Además, puedes usar reglas basadas en consultas para limitar la cantidad de datos que un cliente descarga mediante operaciones de lectura.

Por ejemplo, la siguiente regla limita el acceso de lectura a los primeros 1,000 resultados de una consulta únicamente, los cuales se ordenan 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)

Las siguientes expresiones query. se encuentran disponibles en las reglas de Realtime Database.

Expresiones de reglas basadas en consultas
Expresión Tipo Descripción
query.orderByKey
query.orderByPriority
query.orderByValue
booleano Verdadera para consultas ordenadas según la clave, la prioridad o el valor. De lo contrario, el valor el falso.
query.orderByChild string
nulo
Usa una string para representar la ruta de acceso relativa a un nodo secundario. Por ejemplo, query.orderByChild == "address/zip". Si la consulta no se ordena según un nodo secundario, este valor es nulo.
query.startAt
query.endAt
query.equalTo
string
número
booleano
nulo
Recupera los límites de la consulta en ejecución o muestra el valor nulo si no se estableció ningún límite.
query.limitToFirst
query.limitToLast
número
nulo
Recupera el límite de la consulta en ejecución o muestra el valor nulo si no se estableció ningún límite.

Operadores

Las reglas de Realtime Database admiten una cantidad de operadores que puedes usar para combinar variables en la declaración de condición. Consulta la lista completa de operadores en la documentación de referencia.

Cómo crear condiciones

Tus condiciones reales variarán según el acceso que desees otorgar. Las reglas ofrecen intencionalmente un enorme grado de flexibilidad, por lo que las reglas de tu app pueden ser tan simples o complejas como necesites.

Si deseas obtener información sobre cómo crear reglas simples y listas para la producción, consulta las Reglas básicas de seguridad.