Hinweis
Bevor Sie Realtime Database verwenden können, müssen Sie Folgendes tun:
Registrieren Sie Ihr Unity-Projekt und konfigurieren Sie es für die Verwendung von Firebase.
Wenn in Ihrem Unity-Projekt bereits Firebase verwendet wird, ist es bereits für Firebase registriert und konfiguriert.
Wenn Sie kein Unity-Projekt haben, können Sie eine Beispiel-App herunterladen.
Fügen Sie Ihrem Unity-Projekt das Firebase Unity SDK (insbesondere
FirebaseDatabase.unitypackage
) hinzu.
Das Hinzufügen von Firebase zu Ihrem Unity-Projekt umfasst Aufgaben sowohl in der Firebase Console als auch in Ihrem geöffneten Unity-Projekt. Sie laden beispielsweise Firebase-Konfigurationsdateien aus der Console herunter und verschieben sie dann in Ihr Unity-Projekt.
Daten speichern
Es gibt fünf Methoden, Daten in die Firebase Realtime Database zu schreiben:
Methode | Übliche Anwendungsbereiche |
---|---|
SetValueAsync() |
Daten in einem definierten Pfad schreiben oder ersetzen, z. B. users/<user-id>/<username> . |
SetRawJsonValueAsync() |
Daten mit Roh-JSON schreiben oder ersetzen, z. B. users/<user-id>/<username> . |
Push() |
Zu einer Datenliste hinzufügen Jedes Mal, wenn Sie Push() aufrufen, generiert Firebase einen eindeutigen Schlüssel, der auch als eindeutige Kennung verwendet werden kann, z. B. user-scores/<user-id>/<unique-score-id> . |
UpdateChildrenAsync() |
Einige Schlüssel für einen definierten Pfad aktualisieren, ohne alle Daten zu ersetzen. |
RunTransaction() |
Komplexe Daten aktualisieren, die durch gleichzeitige Aktualisierungen beschädigt werden könnten. |
Datenbankreferenz abrufen
Zum Schreiben von Daten in die Datenbank benötigen Sie eine Instanz von 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; } }
Daten an einer Referenz schreiben, aktualisieren oder löschen
Grundlegende Schreibvorgänge
Bei einfachen Schreibvorgängen können Sie mit SetValueAsync()
Daten unter einer bestimmten Referenz speichern und alle vorhandenen Daten an diesem Pfad ersetzen. Mit dieser Methode können Sie Typen übergeben, die den verfügbaren JSON-Typen entsprechen. Gehen Sie dazu so vor:
string
long
double
bool
Dictionary<string, Object>
List<Object>
Wenn Sie ein typisiertes C#-Objekt verwenden, können Sie die integrierte Funktion JsonUtility.ToJson()
verwenden, um das Objekt in reinen JSON-Code umzuwandeln und SetRawJsonValueAsync()
aufzurufen.
Angenommen, Sie haben eine User-Klasse, die so aussieht:
public class User { public string username; public string email; public User() { } public User(string username, string email) { this.username = username; this.email = email; } }
So fügen Sie einen Nutzer mit SetRawJsonValueAsync()
hinzu:
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); }
Wenn Sie SetValueAsync()
oder SetRawJsonValueAsync()
auf diese Weise verwenden, werden die Daten an diesem Speicherort überschrieben, einschließlich aller untergeordneten Knoten. Sie können ein untergeordnetes Element jedoch aktualisieren, ohne das gesamte Objekt neu zu schreiben. Wenn Sie Nutzern erlauben möchten, ihre Profile zu aktualisieren, können Sie den Nutzernamen so aktualisieren:
mDatabaseRef.Child("users").Child(userId).Child("username").SetValueAsync(name);
Daten an eine Datenliste anhängen
Verwenden Sie die Methode Push()
, um einer Liste in Anwendungen für mehrere Nutzer Daten anzuhängen.
Die Methode Push()
generiert jedes Mal einen eindeutigen Schlüssel, wenn der angegebenen Firebase-Referenz ein neues untergeordnetes Element hinzugefügt wird. Durch die Verwendung dieser automatisch generierten Schlüssel für jedes neue Element in der Liste können mehrere Clients demselben Speicherort gleichzeitig untergeordnete Elemente hinzufügen, ohne dass es zu Schreibkonflikten kommt. Der von Push()
generierte eindeutige Schlüssel basiert auf einem Zeitstempel. Daher werden Listenelemente automatisch chronologisch sortiert.
Sie können die Referenz auf die neuen Daten verwenden, die von der Push()
-Methode zurückgegeben werden, um den Wert des automatisch generierten Schlüssels des untergeordneten Elements abzurufen oder Daten für das untergeordnete Element festzulegen. Wenn Sie Key
für eine Push()
-Referenz aufrufen, wird der Wert des automatisch generierten Schlüssels zurückgegeben.
Bestimmte Felder aktualisieren
Wenn Sie gleichzeitig in bestimmte untergeordnete Elemente eines Knotens schreiben möchten, ohne andere untergeordnete Knoten zu überschreiben, verwenden Sie die Methode UpdateChildrenAsync()
.
Wenn Sie UpdateChildrenAsync()
aufrufen, können Sie untergeordnete Werte der unteren Ebene aktualisieren, indem Sie einen Pfad für den Schlüssel angeben. Wenn Daten zur besseren Skalierung an mehreren Orten gespeichert werden, können Sie alle Instanzen dieser Daten mithilfe der Datenfan-out-Funktion aktualisieren. Ein Spiel könnte beispielsweise eine LeaderboardEntry
-Klasse wie diese haben:
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; } }
Um einen Eintrag in der Bestenliste zu erstellen und gleichzeitig im Feed der letzten Ergebnisse und in der Bestenliste des Nutzers zu aktualisieren, wird im Spiel folgender Code verwendet:
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); }
In diesem Beispiel wird mit Push()
ein Eintrag im Knoten erstellt, der Einträge für alle Nutzer unter /scores/$key
enthält, und gleichzeitig wird der Schlüssel mit Key
abgerufen. Mit dem Schlüssel kann dann ein zweiter Eintrag in den Punktzahlen des Nutzers unter /user-scores/$userid/$key
erstellt werden.
Mit diesen Pfaden können Sie mit einem einzigen Aufruf von UpdateChildrenAsync()
gleichzeitig mehrere Stellen im JSON-Baum aktualisieren. In diesem Beispiel wird beispielsweise der neue Eintrag an beiden Stellen erstellt. Simultane Aktualisierungen auf diese Weise sind atomar: Entweder sind alle Aktualisierungen erfolgreich oder alle schlagen fehl.
Daten löschen
Am einfachsten lassen sich Daten löschen, indem Sie RemoveValue()
auf eine Referenz zum Speicherort dieser Daten anwenden.
Sie können auch löschen, indem Sie null
als Wert für einen anderen Schreibvorgang wie SetValueAsync()
oder UpdateChildrenAsync()
angeben. Sie können diese Methode mit UpdateChildrenAsync()
verwenden, um mehrere untergeordnete Elemente in einem einzigen API-Aufruf zu löschen.
Sie wissen, wann Ihre Daten verbindlich sind.
Wenn Sie wissen möchten, wann Ihre Daten auf dem Firebase Realtime Database-Server verbindlich gespeichert werden, können Sie eine Fortsetzung hinzufügen. Sowohl SetValueAsync()
als auch UpdateChildrenAsync()
geben ein Task
zurück, anhand dessen Sie erkennen können, wann der Vorgang abgeschlossen ist. Wenn der Aufruf aus irgendeinem Grund fehlschlägt, ist IsFaulted
für „Aufgaben“ auf „wahr“ gesetzt und die Property Exception
gibt an, warum der Fehler aufgetreten ist.
Daten als Transaktionen speichern
Wenn Sie mit Daten arbeiten, die durch gleichzeitige Änderungen beschädigt werden könnten, z. B. mit inkrementellen Zählern, können Sie einen Transaktionsvorgang verwenden.
Sie geben diesem Vorgang einen Func
. Bei dieser Aktualisierung Func
wird der aktuelle Status der Daten als Argument übergeben und der neue gewünschte Status zurückgegeben, den Sie schreiben möchten. Wenn ein anderer Client an den Speicherort schreibt, bevor der neue Wert erfolgreich geschrieben wurde, wird die Updatefunktion noch einmal mit dem neuen aktuellen Wert aufgerufen und der Schreibvorgang wird noch einmal versucht.
In einem Spiel können Sie Nutzern beispielsweise erlauben, eine Bestenliste mit den fünf höchsten Punktzahlen zu aktualisieren:
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); }); }
Durch die Verwendung einer Transaktion wird verhindert, dass die Bestenliste falsch ist, wenn mehrere Nutzer gleichzeitig Punkte erzielen oder der Client veraltete Daten hat. Wenn die Transaktion abgelehnt wird, gibt der Server den aktuellen Wert an den Client zurück, der die Transaktion dann noch einmal mit dem aktualisierten Wert ausführt. Dieser Vorgang wird wiederholt, bis die Transaktion akzeptiert wird oder zu viele Versuche unternommen wurden.
Daten offline schreiben
Wenn ein Client die Netzwerkverbindung verliert, funktioniert Ihre App weiterhin ordnungsgemäß.
Jeder Client, der mit einer Firebase-Datenbank verbunden ist, verwaltet seine eigenen internen Versionen aller aktiven Daten. Beim Schreiben von Daten werden sie zuerst in diese lokale Version geschrieben. Der Firebase-Client synchronisiert diese Daten dann auf Best-Effort-Basis mit den Remote-Datenbankservern und anderen Clients.
Daher werden alle Schreibvorgänge in der Datenbank sofort als lokale Ereignisse ausgelöst, bevor Daten auf den Server geschrieben werden. So bleibt Ihre App unabhängig von der Netzwerklatenz oder der Verbindung reaktionsschnell.
Sobald die Verbindung wiederhergestellt ist, erhält Ihre App die entsprechenden Ereignisse, damit der Client mit dem aktuellen Serverstatus synchronisiert wird, ohne dass benutzerdefinierter Code geschrieben werden muss.