Recuperar dados

Como ler dados com GET

É possível ler dados do nosso banco de dados do Firebase ao emitir uma solicitação GET para o endpoint do URL dele. Vamos continuar com o exemplo de blog da seção anterior e ler todos os dados de postagem do blog:

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

Um código de status HTTP 200 OK indica uma solicitação bem-sucedida, e a resposta contém os dados que estamos recuperando.

Como adicionar parâmetros de URI

A API REST aceita diversos parâmetros de consulta ao ler dados do nosso banco de dados do Firebase. Veja abaixo uma lista com os parâmetros mais usados. Veja uma lista completa na Referência da API REST.

auth

Com o parâmetro de solicitação auth, é possível acessar os dados protegidos pelas regras de segurança do Firebase Realtime Database. Além disso, ele é compatível com todos os tipos de solicitação. O argumento pode ser a chave secreta do app do Firebase ou um token de autenticação, conforme descrito em Usuários em projetos do Firebase. No exemplo a seguir, enviamos uma solicitação GET com um parâmetro auth, em que CREDENTIAL é a chave secreta do app do Firebase ou um token de autenticação:

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

print

Ao especificar print=pretty, os dados são retornados em um formato legível.

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

Ao especificar print=silent, um 204 No Content é retornado em caso de êxito.

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

callback

Para fazer chamadas REST de um navegador da Web em vários domínios, é possível usar JSONP para encapsular a resposta em uma função de callback JavaScript. Adicione callback= para que a API REST encapsule os dados retornados na função de callback especificada. Por exemplo:

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

shallow

Esse é um recurso avançado, criado para ajudar você com grandes volumes de dados sem que seja necessário fazer o download de tudo. Para usá-lo, adicione shallow=true como um parâmetro. Isso limitará a profundidade dos dados retornados. Se os dados no local forem um primitivo JSON (string, número ou booleano), o valor dele será simplesmente retornado. Se o snapshot dos dados no local for um objeto JSON, os valores de cada chave serão truncados como true. Por exemplo, usando os dados abaixo:

{
  "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!"

Teste com esta solicitação curl:

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

timeout

Use esse parâmetro para limitar o tempo de leitura no lado do servidor. Se uma solicitação de leitura não terminar dentro do tempo estabelecido, ela será encerrada com um erro HTTP 400. Isso é particularmente útil quando você prevê uma transferência de dados pequena e não quer esperar muito tempo para buscar uma subárvore potencialmente grande. O tempo real de leitura pode variar com base no tamanho dos dados e no armazenamento em cache.

Especifique timeouts usando o seguinte formato: 3ms, 3s ou 3min, com um número e uma unidade. Se não for especificado, o timeout máximo de 15min será aplicado. Se o timeout não for positivo ou exceder o máximo, a solicitação será rejeitada com um erro HTTP 400. No exemplo a seguir, a solicitação GET inclui um timeout de 10 segundos.

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

Como filtrar dados

É possível criar consultas para filtrar dados com base em diversos fatores. Para começar, especifique como você quer que seus dados sejam filtrados usando o parâmetro orderBy. Em seguida, combine orderBy com qualquer um dos outros cinco parâmetros: limitToFirst, limitToLast, startAt, endAt e equalTo.

Como todos nós do Firebase adoramos dinossauros, usaremos um snippet de um banco de dados de exemplo com curiosidades sobre esses animais para demonstrar como você pode filtrar dados:

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

É possível filtrar os dados de três maneiras: por chave filha, por chave ou por valor. Uma consulta começa com um desses parâmetros e precisa ser combinada com um ou mais dos seguintes parâmetros: startAt, endAt, limitToFirst, limitToLast ou equalTo.

Como filtrar por uma chave filha especificada

Podemos filtrar os nós por uma chave filha comum passando essa chave para o parâmetro orderBy. Por exemplo, para recuperar todos os dinossauros com altura superior a 3, podemos fazer isto:

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

Qualquer nó que não tenha a chave filha que estamos filtrando será classificado com um valor null. Para mais detalhes sobre como os dados são ordenados, consulte a seção Ordenação dos dados.

O Firebase também aceita consultas ordenadas por filhos aninhados em níveis profundos, em vez de apenas filhos um nível abaixo. Isso é útil se você tiver dados aninhados em níveis profundos, como estes:

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

Para consultar a altura, usamos o caminho completo para o objeto em vez de uma só chave:

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

As consultas podem ser filtradas somente com uma chave por vez. Usar o parâmetro orderBy várias vezes na mesma solicitação gera um erro.

Como filtrar por chave

Também é possível filtrar nós por chaves usando o parâmetro orderBy="$key". O exemplo a seguir recupera todos os dinossauros com um nome que comece com as letras de a a m:

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

Como filtrar por valor

É possível filtrar os nós pelo valor das chaves filhas usando o parâmetro orderBy="$value". Vamos supor que os dinossauros estejam participando de uma olimpíada jurássica e que estamos monitorando as pontuações no seguinte formato:

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

Para recuperar todos os dinossauros com uma pontuação superior a 50, podemos fazer a seguinte solicitação:

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

Consulte a seção Ordenação dos dados para conferir uma explicação sobre como os valores null, booleano, string e objeto são classificados ao usar orderBy="$value".

Filtros complexos

É possível combinar vários parâmetros para criar consultas mais complexas.

Consultas de limite

Os parâmetros limitToFirst e limitToLast são usados para definir um número máximo de filhos para receber dados. Se definirmos um limite de 100, receberemos somente até 100 filhos correspondentes. Se tivermos menos de 100 mensagens armazenadas no nosso banco de dados, receberemos todos os filhos. No entanto, se tivermos mais de 100 mensagens, receberemos somente os dados de 100 dessas mensagens. Essas mensagens serão as 100 primeiras classificadas se limitToFirst for usado, ou as 100 últimas classificadas se limitToLast for usado.

Usando nosso banco de dados de fatos sobre dinossauros e orderBy, podemos descobrir os dois dinossauros mais pesados:

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

Do mesmo modo, podemos encontrar os dois dinossauros mais baixos usando limitToFirst:

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

Também podemos realizar consultas de limite com orderBy="$value". Se quisermos criar um placar com os três dinossauros que têm a maior pontuação, podemos fazer isto:

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

Consultas de intervalo

O uso de startAt, endAt e equalTo permite escolher pontos arbitrários de início e término para nossas consultas. Por exemplo, para encontrar todos os dinossauros com pelo menos três metros de altura, podemos combinar orderBy e startAt:

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

Podemos usar endAt para encontrar todos os dinossauros cujos nomes venham, alfabeticamente, antes de pterodáctilo:

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

É possível combinar startAt e endAt para limitar as duas extremidades da nossa consulta. Este exemplo descobre todos os dinossauros cujo nome começa com a letra "b":

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

As consultas de intervalo também são úteis quando você precisa paginar seus dados.

Como tudo funciona em conjunto

Podemos combinar todas essas técnicas para criar consultas complexas. Por exemplo, talvez você queira descobrir o nome de todos os dinossauros com altura inferior ou igual à do nosso dinossauro favorito, o estegossauro:

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"

Ordenação dos dados

Veja nesta seção como os dados são classificados ao usar cada um dos três parâmetros de filtro.

orderBy

Ao usar orderBy, os dados que contêm a chave filha especificada serão classificados desta maneira:

  1. Filhos com um valor null para a chave filha especificada são os primeiros.
  2. Filhos com um valor false para a chave filha especificada são os próximos. Se vários filhos tiverem um valor false, eles serão classificados lexicograficamente pela chave.
  3. Filhos com um valor true para a chave filha especificada são os próximos. Se vários filhos tiverem um valor true, eles serão classificados lexicograficamente pela chave.
  4. Filhos com um valor numérico são os próximos, ordenados em ordem crescente. Se vários filhos tiverem o mesmo valor numérico para o nó filho especificado, eles serão ordenados por chave.
  5. As strings vêm depois dos números e são classificadas alfabeticamente em ordem crescente. Se vários filhos tiverem o mesmo valor para o nó filho especificado, eles serão ordenados lexicograficamente por chave.
  6. Os objetos vêm por último e são ordenados alfabeticamente, por chave, em ordem crescente.
Os resultados filtrados são retornados sem classificação. Se a ordem dos dados for importante, classifique os resultados no app depois que eles forem retornados do Firebase.

orderBy="$key"

Ao usar o parâmetro orderBy="$key" para classificar os dados, eles serão retornados em ordem crescente por chave, conforme mostrado a seguir. Lembre-se de que as chaves só podem ser strings.

  1. Filhos com uma chave que possa ser analisada como um número inteiro de 32 bits vêm primeiro, ordenados em ordem crescente.
  2. Filhos com um valor de string como chave são os próximos, classificados de modo lexicográfico em ordem crescente.

orderBy="$value"

Ao usar o parâmetro orderBy="$value" para classificar seus dados, os filhos serão ordenados pelo valor deles. Os critérios de ordenação são os mesmos que os em uma chave filha, mas o valor do nó é usado em vez do valor de uma chave filha especificada.

orderBy="$priority"

Ao usar o parâmetro orderBy="$priority" para classificar os dados, a ordem dos filhos é determinada pela prioridade e pela chave, conforme mostrado a seguir. Lembre-se de que os valores de prioridade podem ser somente números ou strings.

  1. Filhos que não têm prioridade (o padrão) são os primeiros.
  2. Filhos com um número como prioridade são os seguintes. Eles são classificados numericamente por prioridade, do menor ao maior.
  3. Filhos com uma string como prioridade são os últimos. Eles são classificados lexicograficamente por prioridade.
  4. Sempre que dois filhos tiverem a mesma prioridade (incluindo sem prioridade), eles serão classificados por chave. As chaves numéricas são as primeiras (classificadas numericamente), seguidas pelas chaves restantes (classificadas lexicograficamente).

Para mais informações sobre prioridades, consulte a referência da API.

Como fazer stream da API REST

Os endpoints REST do Firebase aceitam o protocolo Eventos EventSource/servidor-Sent, tornando mais fácil fazer stream das alterações para um só local no nosso banco de dados do Firebase.

Para começar a usar o streaming, siga estas etapas:

  1. Defina o cabeçalho Aceitar do cliente como text/event-stream
  2. Respeite os redirecionamentos de HTTP, especificamente o código de status HTTP 307.
  3. Inclua o parâmetro de consulta auth se o local do banco de dados do Firebase precisar de permissão para ler.

Por sua vez, o servidor envia os eventos nomeados como o estado dos dados nas alterações de URL solicitadas. A estrutura dessas mensagens segue o protocolo EventSource:

event: event name
data: JSON encoded data payload

O servidor pode enviar estes eventos:

put Os dados codificados em JSON serão um objeto com duas chaves: caminho e dados
O caminho aponta para um local relativo ao URL de solicitação
O cliente precisa substituir todos os dados nesse local no cache pelos dados fornecidos na mensagem
patch Os dados codificados em JSON serão um objeto com duas chaves: caminho e dados
O caminho aponta para um local relativo ao URL de solicitação
Para cada chave nos dados, o cliente precisa substituir a chave correspondente em seu cache pelos dados dessa chave na mensagem
keep-alive Nenhuma ação é necessária
cancel Os dados deste evento são nulos
Este evento será enviado se as regras de segurança do Firebase Realtime Database fizerem com que uma leitura no local solicitado não seja permitida
auth_revoked Os dados desse evento são uma string que indica que uma credencial expirou
Esse evento será enviado quando o parâmetro de autenticação fornecido não for mais válido

Veja abaixo um exemplo de um conjunto de eventos que o servidor pode 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}}

Se você usar o Go, recomendamos o Firego, um wrapper de terceiros para a API REST e a API Streaming do Firebase.