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

Neste documento, você encontra os conceitos básicos sobre como recuperar, ordenar e filtrar dados do Firebase.

Antes de começar

Configure o app e acesse o banco de dados conforme descrito no guia Get Started.

Como recuperar dados

Os dados do Firebase são recuperados por uma chamada única para GetValue() ou ao anexar a um ValueListener em uma referência FirebaseDatabase. O listener de valor é acionado uma vez para o estado inicial dos dados e novamente quando eles são alterados.

Receber uma referência do banco de dados

Para gravar dados no Database, 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

Use o método GetValue() para ler um instantâneo estático do conteúdo de determinado caminho uma vez. O resultado da tarefa contém um instantâneo com todos os dados do local, incluindo dados filho. Se não houver dados, o instantâneo retornado é null.

  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").GetValue();

Neste ponto, a solicitação já foi feita, mas temos que esperar a classe Future ser concluída para lermos o valor. Como os jogos geralmente são executados em um loop e têm menos chamadas de retorno do que outros apps, você normalmente terá que solicitar 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 alguns erros básicos de verificação. Consulte a referência firebase::Future para mais informações sobre verificação de erros e maneiras de determinar quando o resultado está pronto.

Detectar eventos

É possível adicionar listeners para se inscrever em alterações nos dados:

Classe base ValueListener

Retorno de chamada Uso normal
OnValueChanged Ler e detectar alterações em todo o conteúdo de um caminho.

Classe base OnChildListener

OnChildAdded Recuperar listas de itens ou detectar adições a uma lista de itens. Uso sugerido com OnChildChanged e OnChildRemoved para monitorar alterações nas listas.
OnChildChanged Detectar mudanças em itens de uma lista. Usar com OnChildAdded e OnChildRemoved para monitorar alterações nas listas.
OnChildRemoved Detectar itens sendo removidos de uma lista. Usar com OnChildAdded e OnChildChanged para monitorar alterações nas listas.
OnChildMoved Detectar alterações na classificação dos itens em uma lista ordenada. As chamadas de retorno OnChildMoved sempre seguem as chamadas de retorno OnChildChanged por causa da alteração na ordem do item (com base no seu método atual de ordenação).

Classe ValueListener

Use as chamadas de retorno OnValueChanged para se inscrever nas alterações de conteúdo em determinado caminho. Esse retorno de chamada é acionado uma vez quando o listener é anexado e sempre que houver alteração nos dados e nos dados filho. O retorno de chamada recebe um instantâneo que contém todos os dados no local, incluindo dados filho. Se não houver dados, o instantâneo retornado será null.

O exemplo a seguir demonstra um jogo que recupera 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&ltfirebase::database::DataSnapshot&gt 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 instantâneo retorna uma Variant que representa os dados.

Neste exemplo, o método OnCancelled também é modificado para verificar se a leitura foi cancelada. Por exemplo, uma leitura pode ser cancelada se o cliente não tiver permissão de leitura de um local no banco de dados do Firebase. O database::Error indica o motivo da falha.

Classe ChildListener

Eventos filho são acionados em resposta a operações específicas que ocorrem nos filhos de um node de uma operação, como a adição de um novo filho por meio do método PushChild() ou a atualização de um filho por meio do método UpdateChildren(). Juntos, cada um desses métodos pode ser útil para detectar alterações em um node específico de um banco de dados. Por exemplo, um jogo pode usar esses métodos juntos para monitorar atividades nos comentários de uma sessão do 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&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

Em geral, o retorno de chamada OnChildAdded é usado para recuperar uma lista de itens em um banco de dados do Firebase. O retorno de chamada OnChildAdded é acionado uma vez para cada filho existente e sempre que um novo filho for adicionado ao caminho especificado. O listener recebe um instantâneo que contém os dados do novo filho.

O retorno de chamada OnChildChanged é acionado sempre que um node filho é modificado. Isso inclui modificações nos descendentes do node filho. Em geral, é usado em conjunto com as chamadas OnChildAdded e OnChildRemoved para responder a alterações em uma lista de itens. O instantâneo transferido ao listener contém os dados atualizados do filho.

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

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

Classificar e filtrar dados

Use a classe Query do Realtime Database para recuperar dados classificados por chave, valor ou valor do filho. Também é possível filtrar o resultado classificado por 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 de ordenação para determinar como os resultados são ordenados:

Método Uso
OrderByChild() Ordenar resultados pelo valor de uma chave filha específica.
OrderByKey() Ordenar resultados por chaves filhas.
OrderByValue() Ordenar resultados por valores filhos.

Você pode usar somente um método de ordenação por vez. Chamar um método de ordenação várias vezes na mesma consulta causa um erro.

O exemplo a seguir mostra como se inscrever em um placar classificado 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 uma firebase::Query que, quando combinada a um ValueListener, sincroniza o cliente com o cabeçalho no banco de dados, ordenado pela pontuação de cada entrada. Saiba mais sobre como estruturar seus dados em Estruturar seu banco de dados.

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

Filtrar dados

Para filtrar dados, combine um dos métodos de limite ou de intervalo com um método de ordenação ao criar uma consulta.

Método Uso
LimitToFirst() Definir o número máximo de itens para retornar a partir do início da lista ordenada de resultados.
LimitToLast() Definir o número máximo de itens para retornar a partir do fim da lista ordenada de resultados.
StartAt() Retornar itens maiores ou iguais à chave ou ao valor especificado, dependendo do método de ordenação escolhido.
EndAt() Retornar itens menores ou iguais à chave ou ao valor especificado, dependendo do método de ordenação escolhido.
EqualTo() Retornar itens iguais à chave ou ao valor especificado, dependendo do método de ordenação escolhido.

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

Mesmo quando houver apenas uma correspondência para a consulta, o instantâneo ainda será uma lista, mas contém somente um item.

Limitar o número de resultados

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

Conforme os itens são alterados, você recebe retornos de chamada OnChildAdded para os itens presentes na consulta e retornos de chamada OnChildRemoved para os itens que saem da consulta para que o número total permaneça 100.

Por exemplo, o código abaixo retorna a pontuação máxima de um placar:

  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

Use StartAt(), EndAt() e EqualTo() para escolher pontos arbitrários de início, fim e equivalência para consultas. Isso pode ser útil para paginar dados ou encontrar itens com filhos que tenham um valor específico.

Como os dados de consultas são ordenados

Nesta seção é explicado 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 desta maneira:

  1. Filhos com valor null para a chave filha especificada vêm primeiro.
  2. Filhos com um valor false para a chave filha especificada são os próximos. Se vários filhos tiverem o valor false, eles serão classificados lexicograficamente por 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, classificados em ordem crescente. Se vários filhos tiverem o mesmo valor numérico para o node filho especificado, eles serão classificados por chave.
  5. 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 node filho especificado, eles serão ordenados lexicograficamente por chave.
  6. Objetos vêm por último e são classificados lexicograficamente pela chave em ordem ascendente.

OrderByKey

Ao usar OrderByKey() para classificar seus dados, os dados são retornados em ordem ascendente pelo nome da chave.

  1. Filhos com uma chave que possa ser analisada como um número inteiro de 32 bits vêm primeiro, classificados 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.

OrderByValue

Ao usar OrderByValue(), os filhos são ordenados pelo valor deles. Os critérios de ordenação são os mesmos que os em OrderByChild(), mas o valor do node é usado em vez do valor de uma chave filho especificada.

Próximas etapas

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.