Zanim zaczniesz
Zanim będzie można użyć Realtime Database musisz:
Zarejestruj projekt Unity i skonfiguruj go tak, aby używał Firebase.
Jeśli Twój projekt w Unity korzysta już z Firebase, zarejestrowane i skonfigurowane w Firebase.
Jeśli nie masz projektu Unity, możesz pobrać przykładowej aplikacji.
Dodaj pakiet SDK Firebase Unity (w szczególności
FirebaseDatabase.unitypackage
) do swojego projektu w Unity.
Pamiętaj, że dodanie Firebase do projektu Unity wymaga wykonania zadań zarówno w Firebase i w otwartym projekcie Unity (np. pobierasz z konsoli pliki konfiguracyjne Firebase, do swojego projektu Unity).
Zapisywanie danych
Istnieje pięć metod zapisu danych w Firebase Realtime Database:
Metoda | Typowe zastosowania |
---|---|
SetValueAsync() |
Zapisz lub zastąp dane w określonej ścieżce, takiej jak
users/<user-id>/<username> |
SetRawJsonValueAsync() |
Zapisz lub zastąp dane nieprzetworzonym plikiem JSON, takim jak
users/<user-id>/<username> |
Push() |
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> |
UpdateChildrenAsync() |
zaktualizować niektóre klucze na zdefiniowanej ścieżce bez zastępowania wszystkich danych; |
RunTransaction() |
Aktualizuj złożone dane, które mogą zostać uszkodzone w wyniku równoczesnych aktualizacji. |
Pobieranie odniesienia do bazy danych
Aby zapisać dane w bazie danych, potrzebujesz instancji 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; } }
Zapisywanie, aktualizowanie i usuwanie danych w referencji
Podstawowe operacje zapisu
W przypadku podstawowych operacji zapisu możesz użyć funkcji SetValueAsync()
, 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, które odpowiadają dostępnym typom JSON:
string
long
double
bool
Dictionary<string, Object>
List<Object>
Jeśli używasz typowanego obiektu C#, możesz użyć wbudowanej funkcji JsonUtility.ToJson()
do konwertowania obiektu na surowy JSON i wywołania funkcji SetRawJsonValueAsync()
.
Możesz na przykład mieć klasę użytkownika podobną do tej:
public class User { public string username; public string email; public User() { } public User(string username, string email) { this.username = username; this.email = email; } }
Użytkownika SetRawJsonValueAsync()
możesz dodać w ten sposób:
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); }
Użycie w ten sposób metody SetValueAsync()
lub SetRawJsonValueAsync()
spowoduje zastąpienie danych
w określonej lokalizacji, łącznie ze wszystkimi węzłami podrzędnymi. Nadal możesz jednak
aktualizowania elementu podrzędnego bez przepisywania całego obiektu. Jeśli chcesz zezwolić użytkownikom na aktualizowanie profili, możesz zaktualizować nazwę użytkownika w ten sposób:
mDatabaseRef.Child("users").Child(userId).Child("username").SetValueAsync(name);
Dołącz do listy danych
Użyj metody Push()
, aby dołączać dane do listy w aplikacjach, które mają wielu użytkowników.
Metoda Push()
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ę Push()
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ę Push()
, aby uzyskać
wartość automatycznie wygenerowanego klucza lub zbioru danych wydawcy podrzędnego. Wywołanie funkcji Key
w przypadku odwołania Push()
zwraca wartość klucza wygenerowanego automatycznie.
Zaktualizuj określone pola
Aby jednocześnie zapisywać dane w określonych węzłach podrzędnych bez nadpisywania innych węzłów podrzędnych, użyj metody UpdateChildrenAsync()
.
Podczas wywoływania funkcji UpdateChildrenAsync()
możesz aktualizować wartości podrzędne niższego poziomu, podając ścieżkę 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:
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; } }
utworzyć wpis w tabeli wyników i jednocześnie zaktualizować go do najnowszego wyniku. z własnym źródłem treści i własną listą wyników użytkownika, gra używa takiego kodu:
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); }
W tym przykładzie użyto parametru Push()
do utworzenia w węźle wpisu zawierającego wpisy dla
wszystkich użytkowników w organizacji /scores/$key
i 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 UpdateChildrenAsync()
, 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 również usunąć, określając null
jako wartość innego zapisu
operacji, na przykład SetValueAsync()
lub UpdateChildrenAsync()
. Możesz użyć tej
technika z użyciem UpdateChildrenAsync()
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 serwerze Firebase Realtime Database,
dodać kontynuację. Zarówno SetValueAsync()
, jak i UpdateChildrenAsync()
zwracają wartość Task
, która informuje o zakończeniu operacji. Jeśli
nie uda się z jakiegokolwiek powodu, Lista zadań IsFaulted
zostanie wykonana z
Właściwość Exception
, która wskazuje przyczynę błędu.
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 wartość Func
. Ta aktualizacja Func
przyjmuje bieżący stan
danych jako argumentu i zwraca nowy pożądany stan,
i zapis. Jeśli inny klient zapisze w tej lokalizacji nową wartość, zanim uda się zapisać Twoją nową wartość, funkcja aktualizacji zostanie wywołana ponownie z nową bieżącą wartością i ponownie spróbuje zapisać dane.
Na przykład w grze można zezwolić użytkownikom na aktualizowanie tabeli wyników pięć najwyższych wyników:
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); }); }
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 została odrzucona, serwer zwraca bieżącą wartość klientowi, , co powoduje ponowne uruchomienie transakcji ze zaktualizowaną wartością. Powtarza się do momentu transakcja została zaakceptowana lub dokonano zbyt wielu prób.
Zapisywanie danych offline
Jeśli klient utraci połączenie z siecią, Twoja aplikacja będzie nadal działać prawidłowo.
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.