Recuperar dados

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

Antes de começar

Antes de usar o Realtime Database, você precisa:

  • Registre seu projeto do Unity e configure-o para usar o Firebase.

    • Se o projeto do Unity já usa o Firebase, então ele já está registrado e configurado para essa plataforma.

    • Se você não tiver um projeto do Unity, faça o download de um app de amostra (em inglês).

  • Adicione o SDK do Firebase para Unity (especificamente, FirebaseDatabase.unitypackage) ao seu projeto do Unity.

Adicionar o Firebase ao seu projeto do Unity envolve tarefas no Console do Firebase e no projeto aberto do Unity. Por exemplo, fazer o download dos arquivos de configuração do Firebase no console e movê-los para o projeto do Unity.

Recuperar dados

Os dados do Firebase são recuperados por uma chamada única para GetValueAsync() ou pela anexação a um evento em uma referência FirebaseDatabase. O listener de eventos é acionado uma vez para o estado inicial dos dados e novamente quando eles são alterados.

Receber um DatabaseReference

Para ler dados do banco de dados, você precisará de uma instância de DatabaseReference:

using Firebase;
using Firebase.Database;
using Firebase.Unity.Editor;

public class MyScript: MonoBehaviour {
  void Start() {
    // Set up the Editor before calling into the realtime database.
    FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("https://YOUR-FIREBASE-APP.firebaseio.com/");

    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

Ler dados uma vez

Você pode usar o método GetValueAsync para ler um snapshot estático do conteúdo em um determinado caminho uma vez. O resultado da tarefa terá um snapshot com todos os dados do local, incluindo dados filhos. Se não houver dados, o snapshot retornado será null.

    FirebaseDatabase.DefaultInstance
      .GetReference("Leaders")
      .GetValueAsync().ContinueWith(task => {
        if (task.IsFaulted) {
          // Handle the error...
        }
        else if (task.IsCompleted) {
          DataSnapshot snapshot = task.Result;
          // Do something with snapshot...
        }
      });

Detectar eventos

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

Evento Uso típico
ValueChanged Ler e detectar alterações em todo o conteúdo de um caminho.
ChildAdded Recuperar listas de itens ou detectar adições em uma lista de itens. Sugerir uso com ChildChanged e ChildRemoved para monitor alterações em listas.
ChildChanged Detectar mudanças em itens de uma lista. Use com ChildAdded e ChildRemoved para monitorar alterações em listas.
ChildRemoved Detectar itens sendo removidos de uma lista. Use com ChildAdded e ChildChanged para monitorar alterações em listas.
ChildMoved Detectar mudanças na ordem dos itens em uma lista ordenada. Eventos ChildMoved sempre seguem o evento ChildChanged que causou a mudança da ordem do item (com base no seu método atual "organizar por").

Evento ValueChanged

Você pode usar o evento ValueChanged para se inscrever em mudanças nos conteúdos de determinado caminho. Esse evento é acionado uma vez quando o listener é anexado e sempre que houver alterações nos dados e nos dados filhos. O retorno de chamada do evento recebe um instantâneo que contém todos os dados no local, incluindo dados filhos. Se não houver dados, o snapshot retornado será null.

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

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

ValueChangedEventArgs contém um DataSnapshot que contém os dados no local especificado no banco de dados no momento do evento. Chamando Value em um snapshot retorna um Dictionary<string, object> representando os dados. Se não houver dados no local, chamar Value retornará null.

Neste exemplo, args.DatabaseError também é examinado para conferir 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. DatabaseError indicará o motivo da falha.

Posteriormente, você poderá cancelar a inscrição no evento usando qualquer DatabaseReference com o mesmo caminho. As instâncias DatabaseReference são efêmeras e podem ser consideradas como uma forma de acessar qualquer caminho e consulta.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged -= HandleValueChanged; // unsubscribe from ValueChanged.
    }

Eventos filhos

Eventos filhos são acionados em resposta a operações específicas que ocorrem nos filhos de um nó de uma operação, como a adição de um novo filho por meio do método Push() ou a atualização de um filho pelo método UpdateChildrenAsync(). Juntos, cada um desses métodos pode ser útil para detectar alterações em um nó 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:

      var ref = FirebaseDatabase.DefaultInstance
      .GetReference("GameSessionComments");

      ref.ChildAdded += HandleChildAdded;
      ref.ChildChanged += HandleChildChanged;
      ref.ChildRemoved += HandleChildRemoved;
      ref.ChildMoved += HandleChildMoved;
    }

    void HandleChildAdded(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildChanged(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildRemoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildMoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

Em geral, o evento ChildAdded é usado para recuperar uma lista de itens em um banco de dados. O evento ChildAdded é 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 evento ChildChanged é acionado sempre que um nó filho é modificado. Isso inclui modificações nos descendentes do nó filho. Em geral, ele é usado com os eventos ChildAddede ChildRemoved para responder a alterações em uma lista de itens. O instantâneo transferido ao listener do evento contém os dados atualizados do filho.

O evento ChildRemoved é acionado quando um filho imediato é removido. Ele normalmente é usado em conjunto com os retornos de chamada ChildAdded e ChildChanged. O instantâneo transmitido ao retorno de chamada do evento contém os dados do filho removido.

O evento ChildMoved é acionado sempre que o evento ChildChanged é ativado por uma atualização que causa alteração na ordem do filho. Ele é usado com dados ordenados com OrderByChild ou OrderByValue.

Classificar e filtrar dados

É possível usar a classe Query do Realtime Database para recuperar dados classificados por chave, valor ou valor de 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ê só pode usar 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 ordenado por pontuação.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

Isso define uma consulta que, quando combinada com um listener de eventos valuechanged, sincroniza o cliente com o placar 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 para ordenar os resultados. Nesse 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 há apenas uma correspondência para a consulta, o snapshot ainda é uma lista, mas contém somente um item.

Limitar o número de resultados

Os parâmetros LimitToFirst() e LimitToLast() podem ser usados 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á até 100 retornos de chamada ChildAdded apenas. Se você tiver menos de 100 itens armazenados no banco de dados do Firebase, um retorno de chamada ChildAdded será acionado para cada item.

Conforme os itens forem alterados, você receberá retornos de chamada ChildAdded para os itens que entrarem na consulta e retornos de chamada ChildRemoved para os itens que saírem 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:

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score").LimitToLast(1)
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

Filtrar por chave ou valor

O uso de StartAt(), EndAt() e EqualTo() possibilitará escolher pontos arbitrários de início e fim para as 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 serão ordenados 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, 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. 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. Objetos vêm por último e são classificados lexicograficamente pela chave em ordem crescente.

OrderByKey

Ao usar OrderByKey() para classificar seus dados, eles serão retornados em ordem crescente 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 lexicograficamente em ordem crescente.

OrderByValue

Ao usar OrderByValue(), os filhos serão ordenados pelo próprio valor. Os critérios de ordenação são os mesmos de OrderByChild(), com a exceção de que o valor usado é o do nó, e não o de uma chave filha especificada.