Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Guardar dados

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

Antes de você começar

Antes de poder usar o Realtime Database , você precisa:

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

    • Se o seu projeto Unity já usa o Firebase, ele já está registrado e configurado para o Firebase.

    • Se você não tiver um projeto Unity, poderá baixar um aplicativo de exemplo .

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

Observe que adicionar o Firebase ao seu projeto do Unity envolve tarefas no console do Firebase e em seu projeto Unity aberto (por exemplo, você baixa os arquivos de configuração do Firebase do console e os move para o seu projeto do Unity).

Salvando dados

Existem cinco métodos para gravar dados no Firebase Realtime Database:

Método Usos comuns
SetValueAsync() Grave ou substitua dados em um caminho definido, como users/<user-id>/<username> .
SetRawJsonValueAsync() Grave ou substitua dados por Json bruto, como users/<user-id>/<username> .
Push() Adicionar a uma lista de dados. Sempre que você chama Push() , o Firebase gera uma chave exclusiva que também pode ser usada como um identificador exclusivo, como user-scores/<user-id>/<unique-score-id> .
UpdateChildrenAsync() Atualize algumas das chaves para um caminho definido sem substituir todos os dados.
RunTransaction() Atualize dados complexos que podem ser corrompidos por atualizações simultâneas.

Obter uma referência de banco de dados

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

using Firebase;
using Firebase.Database;

public class MyScript: MonoBehaviour {
  void Start() {
    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

Gravar, atualizar ou excluir dados em uma referência

Operações básicas de gravação

Para operações básicas de gravação, você pode usar SetValueAsync() para salvar dados em uma referência especificada, substituindo quaisquer dados existentes nesse caminho. Você pode usar este método para passar tipos que correspondem aos tipos JSON disponíveis da seguinte forma:

  • string
  • long
  • double
  • bool
  • Dictionary<string, Object>
  • List<Object>

Se você usar um objeto C# digitado, poderá usar o JsonUtility.ToJson() para converter o objeto em Json bruto e chamar SetRawJsonValueAsync() . Por exemplo, você pode ter uma classe User com a seguinte aparência:

public class User {
    public string username;
    public string email;

    public User() {
    }

    public User(string username, string email) {
        this.username = username;
        this.email = email;
    }
}

Você pode adicionar um usuário com SetRawJsonValueAsync() da seguinte maneira:

private void writeNewUser(string userId, string name, string email) {
    User user = new User(name, email);
    string json = JsonUtility.ToJson(user);

    mDatabaseRef.Child("users").Child(userId).SetRawJsonValueAsync(json);
}

Usar SetValueAsync() ou SetRawJsonValueAsync() dessa maneira substitui os dados no local especificado, incluindo quaisquer nós filhos. No entanto, você ainda pode atualizar um filho sem reescrever o objeto inteiro. Se você quiser permitir que os usuários atualizem seus perfis, você pode atualizar o nome de usuário da seguinte forma:

mDatabaseRef.Child("users").Child(userId).Child("username").SetValueAsync(name);

Anexar a uma lista de dados

Use o método Push() para anexar dados a uma lista em aplicativos multiusuário. O método Push() gera uma chave exclusiva sempre que um novo filho é adicionado à referência do Firebase especificada. Usando essas chaves geradas automaticamente para cada novo elemento na lista, vários clientes podem adicionar filhos ao mesmo local ao mesmo tempo sem conflitos de gravação. A chave exclusiva gerada por Push() é baseada em um carimbo de data/hora, portanto, os itens da lista são automaticamente ordenados em ordem cronológica.

Você pode usar a referência aos novos dados retornados pelo método Push() para obter o valor da chave gerada automaticamente pelo filho ou definir dados para o filho. Chamar Key em uma referência Push() retorna o valor da chave gerada automaticamente.

Atualizar campos específicos

Para gravar simultaneamente em filhos específicos de um nó sem substituir outros nós filhos, use o método UpdateChildrenAsync() .

Ao chamar UpdateChildrenAsync() , você pode atualizar valores filho de nível inferior especificando um caminho para a chave. Se os dados forem armazenados em vários locais para dimensionar melhor, você poderá atualizar todas as instâncias desses dados usando distribuição de dados . Por exemplo, um jogo pode ter uma classe LeaderboardEntry como esta:

public class LeaderboardEntry {
    public string uid;
    public int score = 0;

    public LeaderboardEntry() {
    }

    public LeaderboardEntry(string uid, int score) {
        this.uid = uid;
        this.score = score;
    }

    public Dictionary<string, Object> ToDictionary() {
        Dictionary<string, Object> result = new Dictionary<string, Object>();
        result["uid"] = uid;
        result["score"] = score;

        return result;
    }
}

Para criar um LeaderboardEntry e simultaneamente atualizá-lo para o feed de pontuação recente e a lista de pontuação do próprio usuário, o jogo usa um código como este:

private void WriteNewScore(string userId, int score) {
    // Create new entry at /user-scores/$userid/$scoreid and at
    // /leaderboard/$scoreid simultaneously
    string key = mDatabase.Child("scores").Push().Key;
    LeaderBoardEntry entry = new LeaderBoardEntry(userId, score);
    Dictionary<string, Object> entryValues = entry.ToDictionary();

    Dictionary<string, Object> childUpdates = new Dictionary<string, Object>();
    childUpdates["/scores/" + key] = entryValues;
    childUpdates["/user-scores/" + userId + "/" + key] = entryValues;

    mDatabase.UpdateChildrenAsync(childUpdates);
}

Este exemplo usa Push() para criar uma entrada no nó contendo entradas para todos os usuários em /scores/$key e simultaneamente recuperar a chave com Key . A chave pode então ser usada para criar uma segunda entrada nas pontuações do usuário em /user-scores/$userid/$key .

Usando esses caminhos, você pode executar atualizações simultâneas em vários locais na árvore JSON com uma única chamada para UpdateChildrenAsync() , como este exemplo cria a nova entrada em ambos os locais. As atualizações simultâneas feitas dessa maneira são atômicas: todas as atualizações são bem-sucedidas ou todas as atualizações falham.

Excluir dados

A maneira mais simples de excluir dados é chamar RemoveValue() em uma referência ao local desses dados.

Você também pode excluir especificando null como o valor para outra operação de gravação, como SetValueAsync() ou UpdateChildrenAsync() . Você pode usar essa técnica com UpdateChildrenAsync() para excluir vários filhos em uma única chamada de API.

Saiba quando seus dados são confirmados.

Para saber quando seus dados são confirmados no servidor Firebase Realtime Database, você pode adicionar uma continuação. Ambos SetValueAsync() e UpdateChildrenAsync() retornam uma Task que permite que você saiba quando a operação foi concluída. Se a chamada não for bem-sucedida por qualquer motivo, o Tasks IsFaulted será verdadeiro com a propriedade Exception indicando o motivo da falha.

Salvar dados como transações

Ao trabalhar com dados que podem ser corrompidos por modificações simultâneas, como contadores incrementais, você pode usar uma operação de transação . Você atribui a esta operação um Func . Esta função de atualização Func o estado atual dos dados como um argumento e retorna o novo estado desejado que você gostaria de escrever. Se outro cliente gravar no local antes de seu novo valor ser gravado com êxito, sua função de atualização será chamada novamente com o novo valor atual e a gravação será repetida.

Por exemplo, em um jogo, você pode permitir que os usuários atualizem uma tabela de classificação com as cinco pontuações mais altas:

private void AddScoreToLeaders(string email, 
                               long score,
                               DatabaseReference leaderBoardRef) {

    leaderBoardRef.RunTransaction(mutableData => {
      List<object> leaders = mutableData.Value as List<object>

      if (leaders == null) {
        leaders = new List<object>();
      } else if (mutableData.ChildrenCount >= MaxScores) {
        long minScore = long.MaxValue;
        object minVal = null;
        foreach (var child in leaders) {
          if (!(child is Dictionary<string, object>)) continue;
          long childScore = (long)
                      ((Dictionary<string, object>)child)["score"];
          if (childScore < minScore) {
            minScore = childScore;
            minVal = child;
          }
        }
        if (minScore > score) {
          // The new score is lower than the existing 5 scores, abort.
          return TransactionResult.Abort();
        }

        // Remove the lowest score.
        leaders.Remove(minVal);
      }

      // Add the new high score.
      Dictionary<string, object> newScoreMap =
                       new Dictionary<string, object>();
      newScoreMap["score"] = score;
      newScoreMap["email"] = email;
      leaders.Add(newScoreMap);
      mutableData.Value = leaders;
      return TransactionResult.Success(mutableData);
    });
}

O uso de uma transação evita que a tabela de classificação fique incorreta se vários usuários registrarem pontuações ao mesmo tempo ou se o cliente tiver dados obsoletos. Se a transação for rejeitada, o servidor retorna o valor atual para o cliente, que executa novamente a transação com o valor atualizado. Isso se repete até que a transação seja aceita ou muitas tentativas tenham sido feitas.

Gravar dados off-line

Se um cliente perder sua conexão de rede, seu aplicativo continuará funcionando corretamente.

Cada cliente conectado a um banco de dados Firebase mantém sua própria versão interna de todos os dados ativos. Quando os dados são gravados, eles são gravados primeiro nesta versão local. O cliente Firebase sincroniza esses dados com os servidores de banco de dados remotos e com outros clientes com base no "melhor esforço".

Como resultado, todas as gravações no banco de dados acionam eventos locais imediatamente, antes que qualquer dado seja gravado no servidor. Isso significa que seu aplicativo permanece responsivo, independentemente da latência ou conectividade da rede.

Depois que a conectividade é restabelecida, seu aplicativo recebe o conjunto apropriado de eventos para que o cliente sincronize com o estado atual do servidor, sem precisar escrever nenhum código personalizado.

Próximos passos