Cómo recuperar datos

Lee datos con GET

Para leer datos de la base de datos de Firebase, debe enviarse una solicitud GET al extremo URL. Sigamos con el ejemplo del blog que tratamos en la sección anterior y leamos todos los datos de las entradas del blog:

curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=pretty'

Si la solicitud se procesa correctamente, se mostrará un código de estado HTTP 200 OK y la respuesta contendrá los datos que queríamos recuperar.

Agrega parámetros de URI

La API de REST acepta varios parámetros de solicitudes al realizar la lectura de datos de nuestra base de datos de Firebase. A continuación, se mencionan los parámetros usados más comúnmente. Para ver una lista completa, consulta la referencia de API de REST.

auth

El parámetro de solicitud auth permite acceder a los datos protegidos por las reglas de seguridad de Firebase Realtime Database y es compatible con todos los tipos de solicitud. El argumento puede ser el secreto de tu app de Firebase o un token de autenticación, tal como se describe en Usuarios en proyectos de Firebase. En el siguiente ejemplo, enviamos una solicitud GET con un parámetro auth, en el que CREDENTIAL es el secreto de tu app de Firebase o un token de autenticación:

curl 'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'

imprimir

Si se especifica print=pretty, los datos se mostrarán en un formato legible.

curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=pretty'

Si se especifica print=silent, se muestra un 204 No Content en caso de éxito.

curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=silent'

callback

Para realizar llamadas REST desde un navegador web en varios dominios, puedes usar JSONP a fin de unir la respuesta en una función de devolución de llamada de JavaScript. Agrega callback= para que la API de REST incluya los datos mostrados en la función de devolución de llamada que especifiques. Por ejemplo:

<script>
  function gotData(data) {
    console.log(data);
  }
</script>
<script src="https://docs-examples.firebaseio.com/fireblog/posts.json?callback=gotData">

shallow

Esta es una función avanzada que se diseñó para facilitar la tarea de manipular grandes conjuntos de datos sin necesidad de descargarlos todos. Para usarla, agrega shallow=true como parámetro. Esto limita la profundidad de los datos que se muestran. Si los datos en la ubicación son un primitivo de JSON (una string, un número o un booleano), el valor simplemente se mostrará. Si la instantánea de datos en la ubicación es un objeto JSON, los valores de cada clave se reducirán a true. Por ejemplo, con los datos siguientes:

{
  "message": {
    "user": {
      "name": "Chris"
    },
    "body": "Hello!"
  }
}

// A request to /message.json?shallow=true
// would return the following:
{
  "user": true,
  "body": true
}

// A request to /message/body.json?shallow=true
// would simply return:
"Hello!"

Puedes hacer la prueba con esta solicitud curl:

curl 'https://docs-examples.firebaseio.com/rest/retrieving-data.json?shallow=true&print=pretty'

timeout

Úsalo para limitar el tiempo que tarda la lectura en el servidor. Si una solicitud de lectura no termina en el plazo asignado, se cerrará con un error HTTP 400. En particular, es útil cuando deseas realizar una transferencia de datos pequeña y no quieres esperar tanto tiempo para recuperar un subárbol potencialmente grande. Es posible que el tiempo de lectura real varíe según el almacenamiento en caché y el tamaño de los datos.

Especifica timeouts con el siguiente formato: 3ms, 3s o 3min, con un número y una unidad. Si no se especifican, se aplicará el timeout máximo de 15min. Si el timeout no es positivo o excede el máximo, la solicitud se rechazará con un error HTTP 400. En el siguiente ejemplo, la solicitud GET incluye un timeout de 10 segundos.

curl 'https://docs-examples.firebaseio.com/rest/retrieving-data.json?timeout=10s'

Filtra datos

Se pueden crear solicitudes para filtrar datos conforme a varios factores. Para comenzar, especifica cómo quieres que se filtren tus datos con el parámetro orderBy. Luego, debes combinar orderBy con cualquiera de los otros cinco parámetros: limitToFirst, limitToLast, startAt, endAt y equalTo.

En Firebase, a todos nos gustan los dinosaurios. A continuación, usaremos un fragmento de una base de datos de muestra que contiene información sobre dinosaurios para demostrar cómo realizar consultas:

{
  "lambeosaurus": {
    "height": 2.1,
    "length": 12.5,
    "weight": 5000
  },
  "stegosaurus": {
    "height": 4,
    "length": 9,
    "weight": 2500
  }
}

Podemos filtrar los datos de tres maneras: por clave secundaria, por clave o por valor. Una búsqueda comienza con uno de estos parámetros y, luego, debe combinarse con uno o más de los siguientes parámetros: startAt, endAt, limitToFirst, limitToLast o equalTo.

Cómo filtrar según una clave secundaria específica

Podemos filtrar los nodos según una clave secundaria común si pasamos esa clave al parámetro orderBy. Por ejemplo, para recuperar información de todos los dinosaurios con una altura superior a 3 metros, podemos hacer lo siguiente:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&startAt=3&print=pretty'

Cualquier nodo que no tenga la clave secundaria que estamos usando para filtrar se ordenará con un valor de null. Para obtener detalles sobre cómo se ordenan los datos, consulta la sección Cómo se ordenan los datos.

Firebase también admite solicitudes ordenadas por campos secundarios profundamente anidados, en lugar de únicamente por campos secundarios de un nivel inferior. Esto resulta útil si tienes datos profundamente anidados, como estos:

{
  "lambeosaurus": {
    "dimensions": {
      "height" : 2.1,
      "length" : 12.5,
      "weight": 5000
    }
  },
  "stegosaurus": {
    "dimensions": {
      "height" : 4,
      "length" : 9,
      "weight" : 2500
    }
  }
}

Para consultar la altura ahora, usamos la ruta de acceso completa del objeto en lugar de una única clave:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="dimensions/height"&startAt=3&print=pretty'

Las consultas solo pueden filtrarse por una clave a la vez. El uso del parámetro orderBy varias veces en la misma solicitud arroja un error.

Filtra por la clave

También podemos filtrar los nodos según sus claves con el parámetro orderBy="$key". En el siguiente ejemplo, se recuperan todos los nombres de dinosaurios que comienzan con la letra a hasta la m:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&startAt="a"&endAt="m"&print=pretty'

Filtra por valor

Podemos filtrar los nodos por el valor de sus claves secundarias con el parámetro orderBy="$value". Supongamos que los dinosaurios están organizando una competencia deportiva y necesitamos llevar un registro de sus puntuaciones con el siguiente formato:

{
  "scores": {
    "bruhathkayosaurus": 55,
    "lambeosaurus": 21,
    "linhenykus": 80,
    "pterodactyl": 93,
    "stegosaurus": 5,
    "triceratops": 22
  }
}

Para recuperar todos los datos de dinosaurios con puntuaciones superiores a 50, podríamos hacer la siguiente solicitud:

curl 'https://dinosaur-facts.firebaseio.com/scores.json?orderBy="$value"&startAt=50&print=pretty'

Consulta la sección Cómo se ordenan los datos para obtener una explicación sobre cómo se ordenan los valores null, booleanos, de cadena y de objetos cuando se usa orderBy="$value".

Filtros complejos

Es posible combinar varios parámetros para construir consultas más complejas.

Consultas de límites

Los parámetros limitToFirst y limitToLast se usan para establecer una cantidad máxima de elementos secundarios para los cuales recibir datos. Si configuramos un límite de 100, solo recibiremos un máximo de 100 elementos coincidentes. Si tenemos menos de 100 mensajes almacenados en nuestra base de datos, recibiremos todos los elementos secundarios. Sin embargo, si tenemos más de 100 mensajes, solo recibiremos los datos de 100 de esos mensajes. Estos serán los primeros 100 mensajes ordenados si usamos limitToFirst o los últimos 100 mensajes ordenados si usamos limitToLast.

Si usamos nuestra base de datos sobre dinosaurios y orderBy, podemos encontrar los dos dinosaurios más pesados:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="weight"&limitToLast=2&print=pretty'

De manera similar, podemos usar limitToFirst para encontrar los dos dinosaurios de menor estatura:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&limitToFirst=2&print=pretty'

También podemos realizar consultas de límite con orderBy="$value". Si deseamos crear una tabla de clasificación con los tres dinosaurios deportistas que obtuvieron mejores puntajes, podríamos hacer lo siguiente:

curl 'https://dinosaur-facts.firebaseio.com/scores.json?orderBy="$value"&limitToLast=3&print=pretty'

Consultas por rango

Usar startAt, endAt y equalTo nos permite elegir puntos arbitrarios de inicio y de finalización para nuestras búsquedas. Por ejemplo, si quisiéramos encontrar todos los dinosaurios de tres metros de estatura como mínimo, podemos combinar orderBy y startAt:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&startAt=3&print=pretty'

Podemos usar endAt para encontrar todos los dinosaurios cuyos nombres antecedan al pterodáctilo, lexicográficamente. En el siguiente ejemplo, se usa el término "Pterodactyl", en inglés:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&endAt="pterodactyl"&print=pretty'

Podemos combinar startAt y endAt para limitar ambos extremos de nuestra consulta. El siguiente ejemplo permite encontrar todos los dinosaurios cuyos nombres empiecen con la letra "b":

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&startAt="b"&endAt="b\uf8ff"&print=pretty'

Las consultas por rango también son útiles cuando debes paginar tus datos.

Revisión general

Podemos combinar todas estas técnicas para crear consultas complejas. Por ejemplo, supongamos que quieres encontrar el nombre de todos los dinosaurios cuya estatura es inferior o igual a la de nuestra especie favorita, el estegosaurio:

MY_FAV_DINO_HEIGHT=`curl "https://dinosaur-facts.firebaseio.com/dinosaurs/stegosaurus/height.json"`
curl "https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy=\"height\"&endAt=${MY_FAV_DINO_HEIGHT}&print=pretty"

Cómo se ordenan los datos

En esta sección, se explica cómo se ordenan los datos cuando se usa cada uno de los tres parámetros de filtrado.

orderBy

Cuando se usa orderBy con el nombre de una clave secundaria, los datos que contengan la clave secundaria especificada se ordenarán de la siguiente manera:

  1. Los elementos secundarios cuyas claves secundarias especificadas posean el valor null irán en primer lugar.
  2. A continuación, aparecerán los elementos secundarios que tengan el valor false en la clave secundaria especificada. Si hay varios elementos secundarios con el valor false, se ordenan lexicográficamente según la clave.
  3. A continuación, aparecerán los elementos secundarios que tengan el valor true en la clave secundaria especificada. Si hay varios elementos secundarios con el valor true, se ordenan lexicográficamente por clave.
  4. Luego vienen los elementos secundarios con valor numérico, que se ordenan en sentido ascendente. Si varios campos secundarios tienen el mismo valor numérico para el nodo secundario especificado, se ordenan por clave.
  5. Las strings van después de los números y se ordenan de manera lexicográfica, en sentido ascendente. Si varios campos secundarios tienen el mismo valor para el nodo secundario especificado, se ordenan de manera lexicográfica por clave.
  6. Los objetos van al final y se ordenan de manera lexicográfica por clave, en sentido ascendente.
Los resultados filtrados se presentan sin orden. Si el orden de tus datos es importante, debes ordenar los resultados en la aplicación después de recibirlos de Firebase.

orderBy="$key"

Cuando se usa el parámetro orderBy="$key" para ordenar los datos, estos se muestran en orden ascendente por clave de la siguiente manera. Ten en cuenta que las claves solo pueden ser strings.

  1. Los campos secundarios con una clave que pueden analizarse como un elemento entero de 32 bits van primero, ordenados en sentido ascendente.
  2. Los campos secundarios con un valor de string como clave van después y ordenados de manera lexicográfica, en sentido ascendente.

orderBy="$value"

Cuando se usa el parámetro orderBy="$value" para ordenar los datos, los elementos secundarios se ordenan según su valor. Se utilizan los mismos criterios de orden que para los datos ordenados según una clave secundaria, excepto que se usa el valor del nodo en lugar del valor de una clave secundaria especificada.

orderBy="$priority"

Cuando usas el parámetro orderBy="$priority" para ordenar tus datos, el orden de los elementos secundarios se determina según su prioridad y clave de la siguiente manera. Ten en cuenta que los valores de prioridad solo pueden ser números o strings.

  1. Los campos secundarios sin prioridades (predeterminado) van primero.
  2. Los campos secundarios con un número como prioridad van posteriormente. Se ordenan de manera numérica por prioridad, de valores pequeños a grandes.
  3. Los campos secundarios con una string como prioridad van al final. Se ordenan de manera lexicográfica por prioridad.
  4. Cuando dos campos secundarios tienen la misma prioridad (incluidos los casos en que no tienen prioridad), se ordenan por clave. Las claves numéricas van primero (en orden numérico), seguidas por las claves restantes (en orden lexicográfico).

Para obtener más información sobre las prioridades, consulta la referencia de API.

Transmisión desde la API de REST

Los extremos REST de Firebase son compatibles con el protocolo de eventos EventSource/Server-Sent, por lo que es fácil transmitir estos cambios a una sola ubicación en la base de datos de Firebase.

Para comenzar a usar la transmisión, tendremos que hacer lo siguiente:

  1. Establecer el encabezado Accept del cliente en text/event-stream
  2. Respetar los redireccionamientos HTTP; específicamente, el código de estado HTTP 307.
  3. Incluir el parámetro de consulta auth si la ubicación de la base de datos de Firebase necesita permiso para la lectura.

En respuesta, el servidor enviará eventos con nombres como estado de los datos en los cambios de URL solicitados. La estructura de estos mensajes se adecua al protocolo de eventos EventSource:

event: event name
data: JSON encoded data payload

El servidor puede enviar los siguientes eventos:

put Los datos con codificación JSON serán un objeto con dos claves: ruta de acceso y datos.
La ruta de acceso apunta a una ubicación relativa a la URL de solicitud.
El cliente debe reemplazar todos los datos en esa ubicación en su caché con los datos proporcionados en el mensaje.
patch Los datos con codificación JSON serán un objeto con dos claves: ruta de acceso y datos.
La ruta de acceso apunta a una ubicación relativa a la URL de solicitud.
Por cada clave en los datos, el cliente debe reemplazar la clave correspondiente en su caché por los datos de esa clave en el mensaje.
keep-alive Los datos de este evento son nulos, por lo que no se necesita ninguna acción
cancel Los datos de este evento son nulos.
Este evento se enviará si las reglas de seguridad de Firebase Realtime Database hacen que ya no se permita la lectura en la ubicación solicitada.
auth_revoked Los datos de este evento son una string que indica que una credencial venció.
Este evento se enviará cuando el parámetro de auth proporcionado deje de ser válido.

A continuación, se ofrece un ejemplo de un conjunto de eventos que el servidor puede enviar:

// Set your entire cache to {"a": 1, "b": 2}
event: put
data: {"path": "/", "data": {"a": 1, "b": 2}}


// Put the new data in your cache under the key 'c', so that the complete cache now looks like:
// {"a": 1, "b": 2, "c": {"foo": true, "bar": false}}
event: put
data: {"path": "/c", "data": {"foo": true, "bar": false}}


// For each key in the data, update (or add) the corresponding key in your cache at path /c,
// for a final cache of: {"a": 1, "b": 2, "c": {"foo": 3, "bar": false, "baz": 4}}
event: patch
data: {"path": "/c", "data": {"foo": 3, "baz": 4}}

Si usas Go, consulta Firego, un wrapper de terceros para las API de REST y de transmisión de Firebase.