Confira tudo que foi anunciado no Firebase Summit e veja como usar o Firebase para acelerar o desenvolvimento de apps e executar os aplicativos com confiança. Saiba mais

Como recuperar dados com o Firebase Realtime Database para C++

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Este documento aborda os conceitos básicos de recuperação de dados e como ordenar e filtrar dados do Firebase.

Antes de você começar

Verifique se você configurou seu aplicativo e pode acessar o banco de dados conforme abordado no guia de Get Started .

Recuperando dados

Os dados do Firebase são recuperados por uma chamada única para GetValue() ou anexados a um ValueListener em uma referência FirebaseDatabase . O ouvinte de valor é chamado uma vez para o estado inicial dos dados e novamente sempre que os dados são alterados.

Obter uma referência de banco de dados

Para gravar dados no banco de dados, você precisa de uma instância de DatabaseReference :

    // Get the root reference location of the database.
    firebase::database::DatabaseReference dbref = database->GetReference();

Ler dados uma vez

Você pode usar o método GetValue() para ler um instantâneo estático do conteúdo em um determinado caminho uma vez. O resultado da tarefa conterá um instantâneo contendo todos os dados nesse local, incluindo dados filho. Se não houver dados, o instantâneo retornado será null .

  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("Leaders").GetValue();

No ponto em que a solicitação foi feita, mas temos que esperar que o Future seja concluído antes de podermos ler o valor. Como os jogos geralmente são executados em loop e são menos acionados por retorno de chamada do que outros aplicativos, você normalmente pesquisará a conclusão.

  // In the game loop that polls for the result...

  if (result.status() != firebase::kFutureStatusPending) {
    if (result.status() != firebase::kFutureStatusComplete) {
      LogMessage("ERROR: GetValue() returned an invalid result.");
      // Handle the error...
    } else if (result.error() != firebase::database::kErrorNone) {
      LogMessage("ERROR: GetValue() returned error %d: %s", result.error(),
                 result.error_message());
      // Handle the error...
    } else {
      firebase::database::DataSnapshot snapshot = result.result();
      // Do something with the snapshot...
    }
  }

Isso mostra algumas verificações básicas de erros, consulte a referência firebase::Future para obter mais informações sobre verificação de erros e maneiras de determinar quando o resultado está pronto.

Ouça eventos

Você pode adicionar ouvintes para assinar alterações nos dados:

Classe base ValueListener

Ligue de volta Uso típico
OnValueChanged Leia e ouça alterações em todo o conteúdo de um caminho.

classe base OnChildListener

OnChildAdded Recupere listas de itens ou ouça adições a uma lista de itens. Uso sugerido com OnChildChanged e OnChildRemoved para monitorar alterações em listas.
OnChildChanged Ouça as alterações nos itens em uma lista. Use com OnChildAdded e OnChildRemoved para monitorar as alterações nas listas.
OnChildRemoved Ouça os itens que estão sendo removidos de uma lista. Use com OnChildAdded e OnChildChanged para monitorar as alterações nas listas.
OnChildMoved Ouça as alterações na ordem dos itens em uma lista ordenada. Os retornos de chamada OnChildMoved sempre seguem os retornos de chamada OnChildChanged devido à alteração do pedido do item (com base no seu método atual de pedido por).

Classe ValueListener

Você pode usar os retornos de chamada OnValueChanged para assinar as alterações no conteúdo em um determinado caminho. Esse retorno de chamada é acionado uma vez quando o ouvinte é anexado e novamente sempre que os dados, incluindo filhos, são alterados. O retorno de chamada recebe um instantâneo contendo todos os dados nesse local, incluindo dados filho. Se não houver dados, o instantâneo retornado será null .

O exemplo a seguir demonstra um jogo recuperando as pontuações de um placar do banco de dados:

  class LeadersValueListener : public firebase::database::ValueListener {
   public:
    void OnValueChanged(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: LeadersValueListener canceled: %d: %s", error_code,
                 error_message);
    }
  };

  // Elsewhere in the code...

  LeadersValueListener* listener = new LeadersValueListener();
  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

O resultado Future&ltDataSnaphot&gt contém os dados no local especificado no banco de dados no momento do evento. Chamar value() em um snapshot retorna uma Variant que representa os dados.

Neste exemplo, o método OnCancelled também é substituído para ver se a leitura foi cancelada. Por exemplo, uma leitura pode ser cancelada se o cliente não tiver permissão para ler de um local de banco de dados do Firebase. O database::Error indicará por que a falha ocorreu.

Classe ChildListener

Os eventos filho são acionados em resposta a operações específicas que ocorrem com os filhos de um nó de uma operação, como um novo filho adicionado por meio do método PushChild() ou um filho sendo atualizado por meio do método UpdateChildren() . Cada um deles em conjunto pode ser útil para ouvir alterações em um nó específico em um banco de dados. Por exemplo, um jogo pode usar esses métodos juntos para monitorar a atividade nos comentários de uma sessão de jogo, conforme mostrado abaixo:

  class SessionCommentsChildListener : public firebase::database::ChildListener {
   public:
    void OnChildAdded(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildChanged(const firebase::database::DataSnapshot& snapshot,
                        const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildRemoved(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot ...
    }
    void OnChildMoved(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: SessionCommentsChildListener canceled: %d: %s",
                 error_code, error_message);
    }
  };

  // elsewhere ....

  SessionCommentsChildListener* listener = new SessionCommentsChildListener();
  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

O retorno de chamada OnChildAdded normalmente é usado para recuperar uma lista de itens em um banco de dados do Firebase. O retorno de chamada OnChildAdded é chamado uma vez para cada filho existente e novamente sempre que um novo filho é adicionado ao caminho especificado. O ouvinte recebe um instantâneo contendo os dados do novo filho.

O retorno de chamada OnChildChanged é chamado sempre que um nó filho é modificado. Isso inclui quaisquer modificações nos descendentes do nó filho. Normalmente é usado em conjunto com as chamadas OnChildAdded e OnChildRemoved para responder a alterações em uma lista de itens. O instantâneo passado para o ouvinte contém os dados atualizados para o filho.

O retorno de chamada OnChildRemoved é acionado quando um filho imediato é removido. Normalmente é usado em conjunto com os retornos de chamada OnChildAdded e OnChildChanged . O instantâneo passado para o retorno de chamada contém os dados do filho removido.

O retorno de chamada OnChildMoved é acionado sempre que a chamada OnChildChanged é gerada por uma atualização que causa a reordenação do filho. Ele é usado com dados ordenados com OrderByChild ou OrderByValue .

Classificando e filtrando dados

Você pode usar a classe Realtime Database Query para recuperar dados classificados por chave, valor ou valor de um filho. Você também pode filtrar o resultado classificado para um número específico de resultados ou um intervalo de chaves ou valores.

Classificar dados

Para recuperar dados classificados, comece especificando um dos métodos order-by para determinar como os resultados são ordenados:

Método Uso
OrderByChild() Ordene os resultados pelo valor de uma chave filha especificada.
OrderByKey() Ordene os resultados por chaves filhas.
OrderByValue() Ordene os resultados por valores filho.

Você só pode usar um método de pedido por vez. Chamar um método order-by várias vezes na mesma consulta gera um erro.

O exemplo a seguir demonstra como você pode se inscrever em um placar de pontuação ordenado por pontuação.

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score");

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

Isso define um firebase::Query que quando combinado com um ValueListener sincroniza o cliente com o placar no banco de dados, ordenado pela pontuação de cada entrada. Você pode ler mais sobre como estruturar seus dados com eficiência em Estruturar seu banco de dados.

A chamada para o método OrderByChild() especifica a chave filha pela qual ordenar os resultados. Nesse caso, os resultados são classificados pelo valor do valor de "score" em cada filho. Para obter mais informações sobre como outros tipos de dados são ordenados, consulte Como os dados de consulta são ordenados .

Filtrando dados

Para filtrar dados, você pode combinar qualquer um dos métodos de limite ou intervalo com um método de ordenação ao construir uma consulta.

Método Uso
LimitToFirst() Define o número máximo de itens a serem retornados desde o início da lista ordenada de resultados.
LimitToLast() Define o número máximo de itens a serem retornados do final da lista ordenada de resultados.
StartAt() Devolva itens maiores ou iguais à chave ou valor especificado, dependendo do método de ordenação escolhido.
EndAt() Devolva itens menores ou iguais à chave ou valor especificado, dependendo do método de ordenação escolhido.
EqualTo() Retorne itens iguais à chave ou valor especificado, dependendo do método de ordenar por escolhido.

Ao contrário dos métodos de ordenação, você pode combinar várias funções de limite ou intervalo. Por exemplo, você pode combinar os StartAt() e EndAt() para limitar os resultados a um intervalo de valores especificado.

Mesmo quando há apenas uma única correspondência para a consulta, o instantâneo ainda é uma lista; ele contém apenas um único item.

Limitar o número de resultados

Você pode usar os LimitToFirst() e LimitToLast() para definir um número máximo de filhos a serem sincronizados para um determinado retorno de chamada. Por exemplo, se você usar LimitToFirst() para definir um limite de 100, inicialmente receberá apenas 100 retornos de chamada OnChildAdded . Se você tiver menos de 100 itens armazenados no banco de dados do Firebase, um retorno de chamada OnChildAdded acionado para cada item.

À medida que os itens mudam, você recebe retornos de chamada OnChildAdded para itens que inserem a consulta e retornos de chamada OnChildRemoved para itens que saem dela, de modo que o número total permaneça em 100.

Por exemplo, o código abaixo retorna a pontuação máxima de uma tabela de classificação:

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score").LimitToLast(1);

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

Filtrar por chave ou valor

Você pode usar StartAt() , EndAt() e EqualTo() para escolher pontos iniciais, finais e de equivalência arbitrários para consultas. Isso pode ser útil para paginar dados ou localizar itens com filhos que tenham um valor específico.

Como os dados de consulta são ordenados

Esta seção explica como os dados são classificados por cada um dos métodos de ordenação na classe Query .

OrderByChild

Ao usar OrderByChild() , os dados que contêm a chave filha especificada são ordenados da seguinte forma:

  1. Filhos com um valor null para a chave filha especificada vêm primeiro.
  2. Os filhos com um valor false para a chave filha especificada vêm em seguida. Se vários filhos tiverem um valor false , eles serão classificados lexicograficamente por chave.
  3. Os filhos com um valor true para a chave filha especificada vêm em seguida. Se vários filhos tiverem um valor true , eles serão classificados lexicograficamente por chave.
  4. Os filhos com um valor numérico vêm em seguida, classificados em ordem crescente. Se vários filhos tiverem o mesmo valor numérico para o nó filho especificado, eles serão classificados por chave.
  5. As strings vêm depois dos números e são classificadas lexicograficamente 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 classificados lexicograficamente por chave em ordem crescente.

OrderByKey

Ao usar OrderByKey() para classificar seus dados, os dados são retornados em ordem crescente por chave.

  1. Os filhos com uma chave que pode ser analisada como um inteiro de 32 bits vêm primeiro, classificados em ordem crescente.
  2. Os filhos com um valor de string como chave vêm em seguida, classificados lexicograficamente em ordem crescente.

OrderByValue

Ao usar OrderByValue() , os filhos são ordenados por seu valor. Os critérios de ordenação são os mesmos de OrderByChild() , exceto que o valor do nó é usado em vez do valor de uma chave filha especificada.

Próximos passos