Rozpocznij
Jeśli jeszcze nie znasz przewodnika Get Started
, najpierw zapoznaj się z nim.
skonfigurować aplikację i uzyskać dostęp do bazy danych.
Pobieranie odniesienia do bazy danych
Aby zapisać dane w bazie danych, potrzebujesz instancji DatabaseReference
:
// Get the root reference location of the database. firebase::database::DatabaseReference dbref = database->GetReference();
Zapisywanie danych
Dostępne są 4 metody zapisywania danych w interfejsie Firebase Realtime Database:
Metoda | Typowe zastosowania |
---|---|
SetValue() |
Zapisz lub zastąp dane w określonej ścieżce, takiej jak
users/<user-id>/<username> |
PushChild() |
Dodaj do listy danych. Za każdym razem, gdy do Ciebie dzwonisz
Push() , Firebase generuje unikalny klucz, którego można użyć również
jako unikalny identyfikator, np.
user-scores/<user-id>/<unique-score-id> |
UpdateChildren() |
Zaktualizuj niektóre klucze zdefiniowanej ścieżki bez zastępowania wszystkich dane. |
RunTransaction() |
Aktualizuj złożone dane, które mogą zostać uszkodzone w wyniku równoczesnych aktualizacji. |
Zapisywanie, aktualizowanie i usuwanie danych w odwołaniach
Podstawowe operacje zapisu
W przypadku podstawowych operacji zapisu możesz użyć funkcji SetValue()
, aby zapisać dane w
jako odwołania, zastępując wszystkie istniejące dane w tej ścieżce. Możesz użyć tej
do przekazywania typów akceptowanych przez plik JSON za pomocą typu wariantu, który obsługuje:
- Null (spowoduje to usunięcie danych)
- Liczba całkowita (64-bitowa)
- Liczba zmiennoprzecinkowa z podwójną precyzją
- Wartość logiczna
- Ciągi znaków
- Wektory wariantów
- Mapy ciągów znaków na warianty
Użycie tego parametru SetValue()
spowoduje zastąpienie danych w określonej lokalizacji,
łącznie z węzłami podrzędnymi. Nadal możesz jednak zaktualizować dziecko bez
cały obiekt jest tworzony na nowo. Jeśli chcesz zezwolić użytkownikom na aktualizowanie swoich profili
możesz zmienić nazwę użytkownika w następujący sposób:
dbref.Child("users").Child(userId).Child("username").SetValue(name);
Dołącz do listy danych
Użyj metody PushChild()
, aby dołączać dane do listy w aplikacjach, które mają wielu użytkowników.
Metoda PushChild()
generuje unikalny klucz przy każdym nowym kluczu
element podrzędny został dodany do określonego odwołania Firebase. Za pomocą tych
generowanych automatycznie kluczy dla każdego nowego elementu na liście, kilka klientów może
dodawanie dzieci w tym samym czasie do tej samej lokalizacji bez konfliktów zapisu.
unikalny klucz generowany przez usługę PushChild()
jest oparty na sygnaturze czasowej, więc elementy listy są
automatycznie uporządkowane chronologicznie.
Możesz użyć odwołania do nowych danych zwróconych przez metodę PushChild()
, aby pobrać wartość automatycznie wygenerowanego klucza wydawcy podrzędnego lub ustawić dane dla niego.
Wywołanie GetKey()
w przypadku odwołania do PushChild()
zwraca wartość atrybutu
automatycznie wygenerowanego klucza.
Zaktualizuj określone pola
Jednoczesne zapisywanie do określonych elementów podrzędnych węzła bez zastępowania innych
węzłów podrzędnych, użyj metody UpdateChildren()
.
Wywołując UpdateChildren()
, możesz zaktualizować wartości podrzędne niższego poziomu przez
i podaj ścieżkę dostępu do klucza. Jeśli dane są przechowywane w wielu lokalizacjach na potrzeby skalowania
możesz zaktualizować wszystkie wystąpienia tych danych za pomocą funkcji
rozpowszechnianie danych. Na przykład plik
gra może mieć klasę LeaderboardEntry
podobną do tej:
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; } }
Aby utworzyć ocenę LeaderboardEntry
i jednocześnie zaktualizować ją do najnowszej oceny
źródła treści i własnej listy wyników użytkownika, gra używa następującego kodu:
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); }
W tym przykładzie użyto typu PushChild()
do utworzenia wpisu w węźle zawierającym
wpisy dla wszystkich użytkowników w organizacji /scores/$key
oraz jednocześnie pobieraj klucz za pomocą polecenia
key()
Za pomocą klucza można utworzyć drugi wpis w
zdobywa punkty w grupie /user-scores/$userid/$key
.
Korzystając z tych ścieżek, można wprowadzać zmiany w wielu lokalizacjach jednocześnie
drzewo JSON z jednym wywołaniem UpdateChildren()
, na przykład
utworzy nowy wpis w obu lokalizacjach. Równoczesne aktualizacje sprawiły,
są niepodzielne: albo wszystkie aktualizacje zakończą się sukcesem, albo wszystkie aktualizacje kończą się niepowodzeniem.
Usuń dane
Najprostszym sposobem usunięcia danych jest wywołanie funkcji RemoveValue()
w odniesieniu do
lokalizacji danych.
Możesz też usunąć element, określając null
Variant
jako wartość innego zapisu
, na przykład SetValue()
lub UpdateChildren()
. Możesz użyć tej
technika z użyciem UpdateChildren()
umożliwiająca usunięcie wielu elementów podrzędnych w 1 interfejsie API
.
Kontroluj, kiedy dane są udostępniane.
Aby dowiedzieć się, kiedy dane są przekazywane na serwer Firebase Realtime Database, sprawdź: aby osiągnąć sukces w przyszłości.
Zapisywanie danych jako transakcji
Podczas pracy z danymi, które mogły zostać uszkodzone w wyniku równoczesnej pracy
takich jak liczniki przyrostowe, możesz użyć funkcji
operacji transakcji.
Nadaj tej operacji funkcję DoTransaction
. Ta funkcja aktualizacji pobiera
bieżący stan danych jako argument i zwraca nowy pożądany stan
które chcesz napisać. Jeśli inny klient zapisze dane w tej lokalizacji przed
nowa wartość została zapisana, funkcja aktualizacji jest wywoływana ponownie z użyciem
nową bieżącą wartość, a zapis jest ponawiany.
Na przykład w grze można zezwolić użytkownikom na aktualizowanie tabeli wyników pięć najwyższych wyników:
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; }); }
Użycie transakcji zapobiega nieprawidłowej tabeli wyników, jeśli jest ich wiele użytkownicy rejestrują wyniki w tym samym czasie albo klient ma nieaktualne dane. Jeśli transakcja zostanie odrzucona, serwer zwróci klientowi bieżącą wartość, , co powoduje ponowne uruchomienie transakcji ze zaktualizowaną wartością. Powtarza się do momentu transakcja została zaakceptowana lub dokonano zbyt wielu prób.
Zapisuj dane offline
Jeśli klient utraci połączenie sieciowe, aplikacja będzie nadal działać .
Każdy klient połączony z bazą danych Firebase ma własną wersję wewnętrzną wszystkich aktywnych danych. Podczas zapisywania danych są one zapisywane w tej wersji lokalnej . Klient Firebase następnie synchronizuje te dane ze zdalną bazą danych. z serwerami i innymi klientami w ramach „najlepszych starań”, podstaw.
W rezultacie wszystkie zapisy w bazie danych wywołują zdarzenia lokalne natychmiast, przed jakiekolwiek dane są zapisywane na serwerze. Oznacza to, że aplikacja pozostaje niezależnie od opóźnienia sieciowego czy połączenia.
Po przywróceniu połączenia aplikacja otrzyma odpowiedni zestaw zdarzeń, aby klient synchronizował się z bieżącym stanem serwera bez konieczności napisać dowolny niestandardowy kod.