Salva dati

Prima di iniziare

Prima di poter utilizzare Realtime Database, devi:

  • Registra il tuo progetto Unity e configuralo per utilizzare Firebase.

    • Se il tuo progetto Unity utilizza già Firebase, è già registrati e configurati per Firebase.

    • Se non hai un progetto Unity, puoi scaricare un app di esempio.

  • Aggiungi l'SDK Firebase Unity (nello specifico, FirebaseDatabase.unitypackage) a del tuo progetto Unity.

Tieni presente che l'aggiunta di Firebase al progetto Unity comporta attività sia nel Nella console Firebase e nel progetto Unity aperto Ad esempio, scarichi dalla console i file di configurazione di Firebase, quindi li sposti nel tuo progetto Unity).

Risparmio di dati

Esistono cinque metodi per scrivere dati in Firebase Realtime Database:

Metodo Utilizzi comuni
SetValueAsync() Scrivere o sostituire i dati in un percorso definito, ad esempio users/<user-id>/<username>.
SetRawJsonValueAsync() Scrivi o sostituisci i dati con Json non elaborati, come users/<user-id>/<username>.
Push() Aggiungere elementi a un elenco di dati. Ogni volta che chiami Push(), Firebase genera una chiave univoca utilizzabile anche come identificatore univoco, ad esempio user-scores/<user-id>/<unique-score-id>.
UpdateChildrenAsync() Aggiorna alcune chiavi di un percorso definito senza sostituire tutte le chiavi i dati.
RunTransaction() Aggiornare dati complessi che potrebbero essere danneggiati da aggiornamenti simultanei.

Recuperare un DatabaseReference

Per scrivere dati nel database, devi avere un'istanza di 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;
  }
}

Scrivere, aggiornare o eliminare dati in un riferimento

Operazioni di scrittura di base

Per le operazioni di scrittura di base, puoi utilizzare SetValueAsync() per salvare i dati in un riferimento specificato, sostituendo eventuali dati esistenti in quel percorso. Puoi utilizzare questo per passare tipi che corrispondono ai tipi JSON disponibili, come segue:

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

Se utilizzi un oggetto C# digitato, puoi usare la classe JsonUtility.ToJson() incorporata per convertire l'oggetto in Json non elaborato e chiamare SetRawJsonValueAsync(). Ad esempio, potresti avere una classe Utente che ha il seguente aspetto:

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

    public User() {
    }

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

Puoi aggiungere un utente con SetRawJsonValueAsync() nel seguente modo:

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);
}

L'utilizzo di SetValueAsync() o SetRawJsonValueAsync() in questo modo sovrascrive i dati nella località specificata, inclusi eventuali nodi figlio. Tuttavia, puoi ancora aggiornare un asset secondario senza riscrivere l'intero oggetto. Se vuoi consentire agli utenti Per aggiornare i loro profili, puoi aggiornare il nome utente nel seguente modo:

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

Aggiunta a un elenco di dati

Utilizza il metodo Push() per aggiungere dati a un elenco nelle applicazioni multiutente. Il metodo Push() genera una chiave univoca ogni volta che viene al riferimento Firebase specificato. Utilizzando questi chiavi generate automaticamente per ogni nuovo elemento nell'elenco, diversi client possono aggiungi elementi secondari alla stessa località contemporaneamente senza conflitti di scrittura. La chiave univoca generata da Push() si basa su un timestamp, quindi le voci dell'elenco sono in ordine cronologico.

Puoi utilizzare il riferimento ai nuovi dati restituiti dal metodo Push() per ottenere il valore della chiave generata automaticamente dell'elemento secondario o impostare i dati per l'elemento secondario. Chiamata in corso Key su un riferimento Push() restituisce il valore del parametro generata automaticamente.

Aggiorna campi specifici

scrivere contemporaneamente su specifici elementi figlio di un nodo senza sovrascrivere altri nodi figlio, usa il metodo UpdateChildrenAsync().

Quando chiami UpdateChildrenAsync(), puoi aggiornare i valori secondari di livello inferiore specificando un percorso per la chiave. Se i dati vengono archiviati in più posizioni per una scalabilità migliore, puoi aggiornare tutte le istanze utilizzando la distribuzione dei dati. Ad esempio, un potrebbe avere una classe LeaderboardEntry simile a questa:

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&ltstring, Object&gt ToDictionary() {
        Dictionary&ltstring, Object&gt result = new Dictionary&ltstring, Object&gt();
        result["uid"] = uid;
        result["score"] = score;

        return result;
    }
}

Per creare un LeaderboardEntry e aggiornarlo contemporaneamente nel feed dei risultati recenti e nell'elenco dei risultati dell'utente, il gioco utilizza un codice come questo:

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);
}

Questo esempio utilizza Push() per creare una voce nel nodo contenente voci per tutti gli utenti in /scores/$key e recuperare contemporaneamente la chiave con Key. La chiave può quindi essere utilizzata per creare una seconda voce nella punteggi al minuto /user-scores/$userid/$key.

Utilizzando questi percorsi, puoi eseguire aggiornamenti simultanei a più località in ad albero JSON con una singola chiamata a UpdateChildrenAsync(), come crea la nuova voce in entrambe le posizioni. Questo è stato apportato da aggiornamenti simultanei sono atomici: tutti gli aggiornamenti hanno esito positivo o tutti gli aggiornamenti non sono riusciti.

Elimina dati

Il modo più semplice per eliminare i dati è chiamare RemoveValue() su un riferimento al la posizione geografica dei dati.

Puoi anche eseguire l'eliminazione specificando null come valore per un'altra scrittura come SetValueAsync() o UpdateChildrenAsync(). Puoi utilizzare questo con UpdateChildrenAsync() per eliminare più elementi secondari in una singola API chiamata.

Scopri quando viene eseguito il commit dei tuoi dati.

Per sapere quando viene eseguito il commit dei tuoi dati sul server Firebase Realtime Database, può aggiungere una continuazione. Sia SetValueAsync() che UpdateChildrenAsync() restituisce un Task che ti consente di sapere quando l'operazione è stata completata. Se non riesce per qualsiasi motivo, il valore IsFaulted di Tasks sarà true con Proprietà Exception che indica il motivo dell'errore.

Salva i dati come transazioni

Quando si lavora con dati che potrebbero essere danneggiati da istanze modifiche, come i contatori incrementali, puoi utilizzare operazione di transazione. Assegni a questa operazione un valore Func. Questo aggiornamento Func prende lo stato corrente degli argomenti dei dati e restituisce il nuovo stato desiderato che vuoi scrivere. Se un altro client scrive nella posizione prima che il nuovo valore venga scritto correttamente, la funzione di aggiornamento viene richiamata di nuovo con il nuovo valore corrente e la scrittura viene riprovata.

Ad esempio, in un gioco puoi consentire agli utenti di aggiornare una classifica con i cinque punteggi più alti:

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

    leaderBoardRef.RunTransaction(mutableData =&gt {
      List&ltobject&gt leaders = mutableData.Value as List&ltobject>

      if (leaders == null) {
        leaders = new List&ltobject&gt();
      } else if (mutableData.ChildrenCount &gt= MaxScores) {
        long minScore = long.MaxValue;
        object minVal = null;
        foreach (var child in leaders) {
          if (!(child is Dictionary&ltstring, object&gt)) continue;
          long childScore = (long)
                      ((Dictionary&ltstring, object&gt)child)["score"];
          if (childScore &lt minScore) {
            minScore = childScore;
            minVal = child;
          }
        }
        if (minScore &gt 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&ltstring, object&gt newScoreMap =
                       new Dictionary&ltstring, object&gt();
      newScoreMap["score"] = score;
      newScoreMap["email"] = email;
      leaders.Add(newScoreMap);
      mutableData.Value = leaders;
      return TransactionResult.Success(mutableData);
    });
}

L'utilizzo di una transazione impedisce che la classifica sia errata se più utenti registrano i punteggi contemporaneamente o se il client ha dati non aggiornati. Se viene rifiutata, il server restituisce il valore corrente al client che esegue nuovamente la transazione con il valore aggiornato. L'operazione si ripete finché la transazione è stata accettata o sono stati effettuati troppi tentativi.

Scrivi dati offline

Se un client perde la connessione di rete, l'app continuerà a funzionare correttamente.

Ogni client connesso a un database Firebase mantiene la propria versione interna dei dati attivi. Quando i dati vengono scritti, vengono prima scritti in questa versione locale. Il client Firebase sincronizza quindi i dati con i server database remoto e con altri client in base al criterio "best effort".

Di conseguenza, tutte le scritture nel database attivano immediatamente gli eventi locali, prima che qualsiasi dato venga scritto sul server. Ciò significa che la tua app rimane reattivo, indipendentemente dalla latenza o dalla connettività di rete.

Una volta ristabilita la connettività, la tua app riceve l'insieme appropriato di in modo che il client si sincronizzi con lo stato attuale del server, senza dover scrivere codice personalizzato.

Passaggi successivi