Commencer
Consultez d'abord le guide Get Started
si vous n'avez pas encore configuré votre application et l'accès à la base de données.
Obtenir une référence de base de données
Pour écrire des données dans la base de données, vous avez besoin d'une instance de DatabaseReference
:
// Get the root reference location of the database. firebase::database::DatabaseReference dbref = database->GetReference();
Enregistrer des données
Il existe quatre méthodes pour écrire des données dans Firebase Realtime Database:
Méthode | Utilisations courantes |
---|---|
SetValue() |
Écrivez ou remplacez des données dans un chemin défini, tel que users/<user-id>/<username> . |
PushChild() |
Ajouter à une liste de données Chaque fois que vous appelez Push() , Firebase génère une clé unique qui peut également être utilisée comme identifiant unique, par exemple user-scores/<user-id>/<unique-score-id> . |
UpdateChildren() |
Mettez à jour certaines des clés d'un chemin d'accès défini sans remplacer toutes les données. |
RunTransaction() |
Mettez à jour des données complexes qui pourraient être corrompues par des mises à jour simultanées. |
Écrire, mettre à jour ou supprimer des données à une référence
Opérations d'écriture de base
Pour les opérations d'écriture de base, vous pouvez utiliser SetValue()
pour enregistrer des données dans une référence spécifiée, en remplaçant toutes les données existantes de ce chemin d'accès. Vous pouvez utiliser cette méthode pour transmettre des types acceptés par JSON via un type de variante compatible avec:
- Null (cela supprime les données)
- Entiers (64 bits)
- Nombres à virgule flottante à double précision
- Valeurs booléennes
- Strings
- Vecteurs de variantes
- Mappage des chaînes sur les variantes
L'utilisation de SetValue()
de cette manière écrase les données à l'emplacement spécifié, y compris les nœuds enfants. Toutefois, vous pouvez toujours mettre à jour un enfant sans réécrire l'intégralité de l'objet. Si vous souhaitez autoriser les utilisateurs à mettre à jour leur profil, vous pouvez modifier le nom d'utilisateur comme suit:
dbref.Child("users").Child(userId).Child("username").SetValue(name);
Ajouter à une liste de données
Utilisez la méthode PushChild()
pour ajouter des données à une liste dans des applications multi-utilisateurs.
La méthode PushChild()
génère une clé unique chaque fois qu'un nouvel enfant est ajouté à la référence Firebase spécifiée. En utilisant ces clés générées automatiquement pour chaque nouvel élément de la liste, plusieurs clients peuvent ajouter des enfants au même emplacement en même temps sans conflit d'écriture. La clé unique générée par PushChild()
est basée sur un code temporel. Les éléments de la liste sont donc automatiquement triés par ordre chronologique.
Vous pouvez utiliser la référence aux nouvelles données renvoyées par la méthode PushChild()
pour obtenir la valeur de la clé générée automatiquement de l'enfant ou définir des données pour l'enfant.
Appeler GetKey()
sur une référence PushChild()
renvoie la valeur de la clé générée automatiquement.
Mettre à jour des champs spécifiques
Pour écrire simultanément sur des enfants spécifiques d'un nœud sans écraser les autres nœuds enfants, utilisez la méthode UpdateChildren()
.
Lorsque vous appelez UpdateChildren()
, vous pouvez mettre à jour les valeurs enfants de niveau inférieur en spécifiant un chemin d'accès pour la clé. Si les données sont stockées dans plusieurs emplacements pour améliorer leur scaling, vous pouvez mettre à jour toutes les instances de ces données à l'aide de la distribution ramifiée des données. Par exemple, un jeu peut avoir une classe LeaderboardEntry
comme suit:
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; } }
Pour créer un LeaderboardEntry
et le mettre à jour simultanément dans le flux de scores récents et la liste de scores de l'utilisateur, le jeu utilise le code suivant:
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); }
Cet exemple utilise PushChild()
pour créer une entrée dans le nœud contenant des entrées pour tous les utilisateurs à /scores/$key
et récupérer simultanément la clé avec key()
. La clé peut ensuite être utilisée pour créer une deuxième entrée dans les scores de l'utilisateur à /user-scores/$userid/$key
.
À l'aide de ces chemins, vous pouvez effectuer des mises à jour simultanées à plusieurs emplacements de l'arborescence JSON avec un seul appel à UpdateChildren()
, comme dans cet exemple qui crée la nouvelle entrée dans les deux emplacements. Les mises à jour simultanées effectuées de cette manière sont atomiques: toutes les mises à jour réussissent ou toutes échouent.
Supprimer des données
Le moyen le plus simple de supprimer des données consiste à appeler RemoveValue()
sur une référence à l'emplacement de ces données.
Vous pouvez également effectuer une suppression en spécifiant un Variant
null
comme valeur pour une autre opération d'écriture telle que SetValue()
ou UpdateChildren()
. Vous pouvez utiliser cette technique avec UpdateChildren()
pour supprimer plusieurs enfants en un seul appel d'API.
Sachez quand vos données sont validées.
Pour savoir quand vos données sont validées sur le serveur Firebase Realtime Database, vérifiez le résultat Future pour voir s'il est réussi.
Enregistrer les données en tant que transactions
Lorsque vous travaillez avec des données pouvant être corrompues par des modifications simultanées, telles que des compteurs incrémentaux, vous pouvez utiliser une opération de transaction.
Attribuez à cette opération une fonction DoTransaction
. Cette fonction de mise à jour prend l'état actuel des données comme argument et renvoie l'état souhaité que vous souhaitez écrire. Si un autre client écrit sur l'emplacement avant que la nouvelle valeur ne soit écrite, votre fonction de mise à jour est rappelée avec la nouvelle valeur actuelle, et l'écriture est relancée.
Par exemple, dans un jeu, vous pouvez autoriser les utilisateurs à mettre à jour un classement avec les cinq meilleurs scores:
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; }); }
L'utilisation d'une transaction empêche le classement d'être incorrect si plusieurs utilisateurs enregistrent des scores en même temps ou si le client dispose de données obsolètes. Si la transaction est refusée, le serveur renvoie la valeur actuelle au client, qui exécute à nouveau la transaction avec la valeur mise à jour. Cette opération se répète jusqu'à ce que la transaction soit acceptée ou que trop de tentatives aient été effectuées.
Écrire des données hors connexion
Si un client perd sa connexion réseau, votre application continue de fonctionner correctement.
Chaque client connecté à une base de données Firebase gère sa propre version interne de toutes les données actives. Lorsque des données sont écrites, elles le sont d'abord dans cette version locale. Le client Firebase synchronise ensuite ces données avec les serveurs de base de données distants et avec d'autres clients dans la mesure du possible.
Par conséquent, toutes les écritures dans la base de données déclenchent immédiatement des événements locaux, avant que des données ne soient écrites sur le serveur. Cela signifie que votre application reste réactive quelle que soit la latence ou la connectivité du réseau.
Une fois la connectivité rétablie, votre application reçoit l'ensemble d'événements approprié pour que le client se synchronise avec l'état actuel du serveur, sans avoir à écrire de code personnalisé.