Jetzt starten
Wenn Sie Ihre App und den Zugriff auf die Datenbank noch nicht
eingerichtet haben, lesen Sie zuerst die Get Started Anleitung.
DatabaseReference abrufen
Wenn Sie Daten in die Datenbank schreiben möchten, benötigen Sie eine Instanz von DatabaseReference:
// Get the root reference location of the database. firebase::database::DatabaseReference dbref = database->GetReference();
Daten speichern
Es gibt vier Methoden zum Schreiben von Daten in die Firebase Realtime Database:
| Methode | Gängige Einsatzmöglichkeiten |
|---|---|
SetValue() |
Daten in einen definierten Pfad schreiben oder ersetzen, z. B.
users/<user-id>/<username>. |
PushChild() |
Daten einer Liste hinzufügen. Jedes Mal, wenn Sie
Push() aufrufen, generiert Firebase einen eindeutigen Schlüssel, der auch als eindeutige ID verwendet werden kann,
z. B.
user-scores/<user-id>/<unique-score-id>. |
UpdateChildren() |
Einige der 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. |
Daten an einer Referenz schreiben, aktualisieren oder löschen
Grundlegende Schreibvorgänge
Für grundlegende Schreibvorgänge können Sie mit SetValue() Daten an einer bestimmten Referenz speichern und dabei alle vorhandenen Daten an diesem Pfad ersetzen. Mit dieser Methode können Sie Typen, die von JSON akzeptiert werden, über einen Variant-Typ übergeben, der Folgendes unterstützt:
- Null (dadurch werden die Daten gelöscht)
- Ganzzahlen (64 Bit)
- Gleitkommazahlen mit doppelter Genauigkeit
- Boolesche Werte
- Strings
- Vektoren von Varianten
- Zuordnungen von Strings zu Varianten
Wenn Sie SetValue() auf diese Weise verwenden, werden die Daten am angegebenen Speicherort überschrieben, einschließlich aller untergeordneten Knoten. Sie können jedoch weiterhin ein untergeordnetes Element 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:
dbref.Child("users").Child(userId).Child("username").SetValue(name);
Daten einer Liste hinzufügen
Verwenden Sie die Methode PushChild(), um Daten in Mehrnutzeranwendungen einer Liste hinzuzufügen.
Die Methode PushChild() generiert jedes Mal einen eindeutigen Schlüssel, wenn der angegebenen Firebase-Referenz ein neues untergeordnetes Element hinzugefügt wird. Wenn Sie diese automatisch generierten Schlüssel für jedes neue Element in der Liste verwenden, können mehrere Clients gleichzeitig untergeordnete Elemente am selben Speicherort hinzufügen, ohne dass es zu Schreibkonflikten kommt. Der von PushChild() generierte eindeutige Schlüssel basiert auf einem Zeitstempel, sodass Listenelemente automatisch chronologisch sortiert werden.
Mit der Referenz auf die neuen Daten, die von der Methode PushChild() zurückgegeben werden, können Sie den Wert des automatisch generierten Schlüssels des untergeordneten Elements abrufen oder Daten für das untergeordnete Element festlegen.
Wenn Sie GetKey() für eine PushChild()-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 UpdateChildren().
Wenn Sie UpdateChildren() aufrufen, können Sie untergeordnete Werte auf niedrigerer Ebene aktualisieren, indem Sie einen Pfad für den Schlüssel angeben. Wenn Daten zur besseren Skalierung an mehreren Speicherorten gespeichert sind, können Sie alle Instanzen dieser Daten mit
Data Fan-Outaktualisieren. Ein Spiel kann beispielsweise eine LeaderboardEntry-Klasse wie diese haben:
class LeaderboardEntry { std::string uid; int score = 0; public: LeaderboardEntry() { } LeaderboardEntry(std::string uid, int score) { this->uid = uid; this->score = score; } std::map<std::string, Object> ToMap() { std::map<string, Variant> result = new std::map<string, Variant>(); result["uid"] = Variant(uid); result["score"] = Variant(score); return result; } }
Wenn Sie einen LeaderboardEntry erstellen und gleichzeitig mit dem aktuellen Score-Feed und der eigenen Score-Liste des Nutzers aktualisieren möchten, verwendet das Spiel den folgenden Code:
void WriteNewScore(std::string userId, int score) { // Create new entry at /user-scores/$userid/$scoreid and at // /leaderboard/$scoreid simultaneously std::string key = dbref.Child("scores").PushChild().GetKey(); LeaderBoardEntry entry = new LeaderBoardEntry(userId, score); std::map<std::string, Variant> entryValues = entry.ToMap(); std::map<string, Variant> childUpdates = new std::map<string, Variant>(); childUpdates["/scores/" + key] = entryValues; childUpdates["/user-scores/" + userId + "/" + key] = entryValues; dbref.UpdateChildren(childUpdates); }
In diesem Beispiel wird PushChild() verwendet, um einen Eintrag im Knoten mit Einträgen für alle Nutzer unter /scores/$key zu erstellen und gleichzeitig den Schlüssel mit key() abzurufen. Der Schlüssel kann dann verwendet werden, um einen zweiten Eintrag in den Scores des Nutzers unter /user-scores/$userid/$key zu erstellen.
Mit diesen Pfaden können Sie mit einem einzigen Aufruf von UpdateChildren() gleichzeitige Aktualisierungen an mehreren Speicherorten in der JSON-Struktur vornehmen. In diesem Beispiel wird der neue Eintrag an beiden Speicherorten erstellt. Gleichzeitige Aktualisierungen, die auf diese Weise vorgenommen werden, sind atomar: Entweder sind alle Aktualisierungen erfolgreich oder alle Aktualisierungen schlagen fehl.
Daten löschen
Die einfachste Möglichkeit, Daten zu löschen, besteht darin, RemoveValue() für eine Referenz auf den Speicherort dieser Daten aufzurufen.
Sie können auch löschen, indem Sie eine null-Variant als Wert für einen anderen Schreibvorgang wie SetValue() oder UpdateChildren() angeben. Mit dieser Technik können Sie mit UpdateChildren() mehrere untergeordnete Elemente in einem einzigen API-Aufruf löschen.
Wissen, wann Ihre Daten übernommen wurden
Wenn Sie wissen möchten, wann Ihre Daten auf dem Firebase Realtime Database Server übernommen wurden, prüfen Sie , ob das Future Ergebnis erfolgreich war.
Daten als Transaktionen speichern
Wenn Sie mit Daten arbeiten, die durch gleichzeitige
Änderungen beschädigt werden könnten, z. B. inkrementelle Zähler, können Sie einen
Transaktionsvorgang verwenden.
Sie geben dieser Operation eine DoTransaction-Funktion. Diese Aktualisierungsfunktion verwendet den aktuellen Status der Daten als Argument und gibt den neuen gewünschten Status zurück, den Sie schreiben möchten. Wenn ein anderer Client an den Speicherort schreibt, bevor Ihr neuer Wert erfolgreich geschrieben wurde, wird Ihre Aktualisierungsfunktion noch einmal mit dem neuen aktuellen Wert aufgerufen und der Schreibvorgang wird wiederholt.
In einem Spiel könnten Sie Nutzern beispielsweise erlauben, eine Bestenliste mit den fünf höchsten Scores zu aktualisieren:
void AddScoreToLeaders(std::string email, long score, DatabaseReference leaderBoardRef) { leaderBoardRef.RunTransaction([](firebase::database::MutableData* mutableData) { if (mutableData.children_count() >= MaxScores) { long minScore = LONG_MAX; MutableData *minVal = null; std::vector<MutableData> children = mutableData.children(); std::vector<MutableData>::iterator it; for (it = children.begin(); it != children.end(); ++it) { if (!it->value().is_map()) continue; long childScore = (long)it->Child("score").value().int64_value(); if (childScore < minScore) { minScore = childScore; minVal = &*it; } } if (minScore > score) { // The new score is lower than the existing 5 scores, abort. return kTransactionResultAbort; } // Remove the lowest score. children.Remove(minVal); } // Add the new high score. std::map<std::string, Variant> newScoreMap = new std::map<std::string, Variant>(); newScoreMap["score"] = score; newScoreMap["email"] = email; children.Add(newScoreMap); mutableData->set_value(children); return kTransactionResultSuccess; }); }
Durch die Verwendung einer Transaktion wird verhindert, dass die Bestenliste falsch ist, wenn mehrere Nutzer gleichzeitig Scores aufzeichnen oder der Client veraltete Daten hatte. Wenn die Transaktion abgelehnt wird, gibt der Server den aktuellen Wert an den Client zurück, der die Transaktion mit dem aktualisierten Wert noch einmal 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 eine eigene interne Version aller aktiven Daten. Wenn Daten geschrieben werden, werden sie zuerst in diese lokale Version geschrieben. Der Firebase-Client synchronisiert diese Daten dann nach dem Best-Effort-Prinzip mit den Remote-Datenbankservern und mit anderen Clients.
Daher lösen alle Schreibvorgänge in die Datenbank sofort lokale Ereignisse aus, bevor Daten auf den Server geschrieben werden. Das bedeutet, dass Ihre App unabhängig von Netzwerklatenz oder Konnektivität reaktionsschnell bleibt.
Sobald die Verbindung wiederhergestellt ist, empfängt Ihre App die entsprechenden Ereignisse, sodass der Client mit dem aktuellen Serverstatus synchronisiert wird, ohne dass Sie benutzerdefinierten Code schreiben müssen.