Pobieram dane

Z tego dokumentu dowiesz się, jak pobierać dane oraz jak sortować i filtrować dane Firebase.

Zanim zaczniesz

Zanim zaczniesz korzystać z Realtime Database, musisz:

  • zarejestrować projekt w Unity i skonfigurować go do korzystania z Firebase.

    • Jeśli Twój projekt w Unity korzysta już z Firebase, jest on już zarejestrowany i skonfigurowany pod kątem Firebase.

    • Jeśli nie masz projektu w Unity, możesz pobrać przykładową aplikację.

  • dodać pakiet Firebase Unity SDK (konkretnie FirebaseDatabase.unitypackage) do projektu w Unity.

Pamiętaj, że dodanie Firebase do projektu w Unity wymaga wykonania zadań zarówno w Firebase konsoli jak i w otwartym projekcie w Unity (np. pobierasz pliki konfiguracyjne Firebase z konsoli, a następnie przenosisz je do projektu w Unity).

Pobieranie danych

Dane Firebase są pobierane przez jednorazowe wywołanie funkcji GetValueAsync() lub przez dołączenie do zdarzenia w odniesieniu FirebaseDatabase. Detektor zdarzeń jest wywoływany raz w przypadku stanu początkowego danych i ponownie za każdym razem, gdy dane się zmienią.

Pobieranie DatabaseReference

Aby odczytać dane z bazy danych, potrzebujesz instancji DatabaseReference:

using Firebase;
using Firebase.Database;
using Firebase.Extensions.TaskExtension; // for ContinueWithOnMainThread

public class MyScript: MonoBehaviour {
  void Start() {
    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

Jednorazowe odczytywanie danych

Za pomocą metody GetValueAsync możesz jednorazowo odczytać statyczny zrzut zawartości w danej ścieżce. Wynik zadania będzie zawierał zrzut ze wszystkimi danymi w tej lokalizacji, w tym z danymi podrzędnymi. Jeśli nie ma danych, zwracany zrzut to null.

    FirebaseDatabase.DefaultInstance
      .GetReference("Leaders")
      .GetValueAsync().ContinueWithOnMainThread(task =&gt {
        if (task.IsFaulted) {
          // Handle the error...
        }
        else if (task.IsCompleted) {
          DataSnapshot snapshot = task.Result;
          // Do something with snapshot...
        }
      });

Nasłuchiwanie zdarzeń

Możesz dodać detektory zdarzeń, aby subskrybować zmiany danych:

Zdarzenie Typowe użycie
ValueChanged Odczytywanie i nasłuchiwanie zmian całej zawartości ścieżki.
ChildAdded Pobieranie list elementów lub nasłuchiwanie dodatków do listy elementów. Sugerowane użycie z ChildChanged i ChildRemoved do monitorowania zmian na listach.
ChildChanged Nasłuchiwanie zmian elementów na liście. Używaj z ChildAdded i ChildRemoved do monitorowania zmian na listach.
ChildRemoved Nasłuchiwanie elementów usuwanych z listy. Używaj z ChildAdded i ChildChanged do monitorowania zmian na listach.
ChildMoved Nasłuchiwanie zmian kolejności elementów na uporządkowanej liście. ChildMoved zdarzenia zawsze następują po zdarzeniu ChildChanged które spowodowało zmianę kolejności elementu (na podstawie bieżącej metody sortowania).

Zdarzenie ValueChanged

Za pomocą zdarzenia ValueChanged możesz subskrybować zmiany zawartości w danej ścieżce. To zdarzenie jest wywoływane raz po dołączeniu detektora i ponownie za każdym razem, gdy zmienią się dane, w tym dane podrzędne. Wywołanie zwrotne zdarzenia otrzymuje zrzut zawierający wszystkie dane w tej lokalizacji, w tym dane podrzędne. Jeśli nie ma danych, zwracany zrzut to null.

Poniższy przykład pokazuje grę, która pobiera wyniki z tabeli wyników z bazy danych:

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

ValueChangedEventArgs zawiera DataSnapshot, który zawiera dane w określonej lokalizacji w bazie danych w momencie zdarzenia. Wywołanie Value w zrzucie zwraca Dictionary<string, object> reprezentujący dane. Jeśli w danej lokalizacji nie ma danych, wywołanie Value zwraca null.

W tym przykładzie sprawdzany jest też args.DatabaseError, aby sprawdzić, czy odczyt został anulowany. Odczyt może zostać anulowany np. wtedy, gdy klient nie ma uprawnień do odczytu z lokalizacji bazy danych Firebase. DatabaseError wskaże przyczynę niepowodzenia.

Później możesz zrezygnować z subskrypcji zdarzenia za pomocą dowolnego DatabaseReference, który ma tę samą ścieżkę. Instancje DatabaseReference są efemeryczne i można je traktować jako sposób na dostęp do dowolnej ścieżki i zapytania.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged -= HandleValueChanged; // unsubscribe from ValueChanged.
    }

Zdarzenia podrzędne

Zdarzenia podrzędne są wywoływane w odpowiedzi na określone operacje wykonywane na elementach podrzędnych węzła, takie jak dodanie nowego elementu podrzędnego za pomocą Push() metody lub zaktualizowanie elementu podrzędnego za pomocą UpdateChildrenAsync() metody. Każde z nich może być przydatne do nasłuchiwania zmian w określonym węźle w bazie danych. Na przykład gra może używać tych metod razem do monitorowania aktywności w komentarzach sesji gry, jak pokazano poniżej:

      var ref = FirebaseDatabase.DefaultInstance
      .GetReference("GameSessionComments");

      ref.ChildAdded += HandleChildAdded;
      ref.ChildChanged += HandleChildChanged;
      ref.ChildRemoved += HandleChildRemoved;
      ref.ChildMoved += HandleChildMoved;
    }

    void HandleChildAdded(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildChanged(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildRemoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildMoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

Zdarzenie ChildAdded jest zwykle używane do pobierania listy elementów w bazie danych Firebase. Zdarzenie ChildAdded jest wywoływane raz dla każdego istniejącego elementu podrzędnego, a następnie za każdym razem, gdy do określonej ścieżki zostanie dodany nowy element podrzędny. Detektor otrzymuje zrzut zawierający dane nowego elementu podrzędnego.

Zdarzenie ChildChanged jest wywoływane za każdym razem, gdy węzeł podrzędny zostanie zmodyfikowany. Obejmuje to wszelkie modyfikacje elementów podrzędnych węzła podrzędnego. Jest zwykle używane w połączeniu ze zdarzeniami ChildAdded i ChildRemoved w celu reagowania na zmiany na liście elementów. Zrzut przekazywany do detektora zdarzeń zawiera zaktualizowane dane elementu podrzędnego.

Zdarzenie ChildRemoved jest wywoływane, gdy zostanie usunięty bezpośredni element podrzędny. Jest zwykle używane w połączeniu z wywołaniami zwrotnymi ChildAdded i ChildChanged. Zrzut przekazywany do wywołania zwrotnego zdarzenia zawiera dane usuniętego elementu podrzędnego.

Zdarzenie ChildMoved jest wywoływane za każdym razem, gdy zdarzenie ChildChanged jest wywoływane przez aktualizację, która powoduje zmianę kolejności elementu podrzędnego. Jest używane z danymi, które są uporządkowane za pomocą OrderByChild lub OrderByValue.

Sortowanie i filtrowanie danych

Za pomocą klasy Realtime Database Query możesz pobierać dane posortowane według klucza, wartości lub wartości elementu podrzędnego. Możesz też filtrować posortowany wynik do określonej liczby wyników lub zakresu kluczy lub wartości.

Sortowanie danych

Aby pobrać posortowane dane, zacznij od określenia jednej z metod sortowania, która określi kolejność wyników:

Metoda Wykorzystanie
OrderByChild() Sortowanie wyników według wartości określonego klucza podrzędnego.
OrderByKey() Sortowanie wyników według kluczy podrzędnych.
OrderByValue() Sortowanie wyników według wartości podrzędnych.

W danym momencie możesz użyć tylko 1 metody sortowania. Wywołanie metody sortowania kilka razy w tym samym zapytaniu powoduje błąd.

Poniższy przykład pokazuje, jak można subskrybować tabelę wyników posortowaną według wyniku.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

Definiuje to zapytanie, które w połączeniu z detektorem zdarzeń valuechanged synchronizuje klienta z tabelą wyników w bazie danych, posortowaną według wyniku każdego wpisu. Więcej informacji o efektywnym strukturyzowaniu danych znajdziesz w artykule Struktura bazy danych.

Wywołanie metody OrderByChild() określa klucz podrzędny, według którego mają być sortowane wyniki. W tym przypadku wyniki są sortowane według wartości "score" w każdym elemencie podrzędnym. Więcej informacji o tym, jak są sortowane inne typy danych, zobacz Jak są sortowane dane zapytań.

Filtrowanie danych

Aby filtrować dane, możesz połączyć dowolną z metod limitu lub zakresu z metodą sortowania podczas tworzenia zapytania.

Metoda Wykorzystanie
LimitToFirst() Ustawia maksymalną liczbę elementów, które mają być zwracane od początku uporządkowanej listy wyników.
LimitToLast() Ustawia maksymalną liczbę elementów, które mają być zwracane od końca uporządkowanej listy wyników.
StartAt() Zwraca elementy większe lub równe określonemu kluczowi lub wartości w zależności od wybranej metody sortowania.
EndAt() Zwraca elementy mniejsze lub równe określonemu kluczowi lub wartości w zależności od wybranej metody sortowania.
EqualTo() Zwraca elementy równe określonemu kluczowi lub wartości w zależności od wybranej metody sortowania.

W przeciwieństwie do metod sortowania możesz łączyć ze sobą kilka funkcji limitu lub zakresu. Możesz na przykład połączyć metody StartAt() i EndAt(), aby ograniczyć wyniki do określonego zakresu wartości.

Nawet jeśli zapytanie znajdzie tylko 1 pasujący element, zrzut nadal będzie listą, tylko z 1 elementem.

Ograniczanie liczby wyników

Za pomocą metod LimitToFirst() i LimitToLast() możesz ustawić maksymalną liczbę elementów podrzędnych, które mają być synchronizowane w przypadku danego wywołania zwrotnego. Jeśli na przykład użyjesz LimitToFirst() do ustawienia limitu 100, początkowo otrzymasz tylko do 100 wywołań zwrotnych ChildAdded. Jeśli w bazie danych Firebase masz mniej niż 100 elementów, wywołanie zwrotne ChildAdded zostanie wywołane dla każdego elementu.

Gdy elementy się zmieniają, otrzymujesz wywołania zwrotne ChildAdded dla elementów, które wchodzą w zakres zapytania, oraz wywołania zwrotne ChildRemoved dla elementów, które z niego wypadają, tak aby łączna liczba elementów pozostała na poziomie 100.

Na przykład poniższy kod zwraca najlepszy wynik z tabeli wyników:

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score").LimitToLast(1)
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

Filtrowanie według klucza lub wartości

Za pomocą StartAt(), EndAt() i EqualTo() możesz wybrać dowolne punkty początkowe, końcowe i równoważne dla zapytań. Może to być przydatne do paginacji danych lub znajdowania elementów z elementami podrzędnymi, które mają określoną wartość.

Jak są sortowane dane zapytań

W tej sekcji wyjaśniamy, jak dane są sortowane przez każdą z metod sortowania w klasie Query.

OrderByChild

Gdy używasz OrderByChild() , dane zawierające określony klucz podrzędny są sortowane w ten sposób:

  1. Najpierw są wyświetlane elementy podrzędne z wartością null dla określonego klucza podrzędnego.
  2. Następnie są wyświetlane elementy podrzędne z wartością false dla określonego klucza podrzędnego. Jeśli kilka elementów podrzędnych ma wartość false, są one sortowane leksykograficznie według klucza.
  3. Następnie są wyświetlane elementy podrzędne z wartością true dla określonego klucza podrzędnego. Jeśli kilka elementów podrzędnych ma wartość true, są one sortowane leksykograficznie według klucza.
  4. Następnie są wyświetlane elementy podrzędne z wartością liczbową, posortowane w kolejności rosnącej. Jeśli kilka elementów podrzędnych ma tę samą wartość liczbową dla określonego węzła podrzędnego, są one sortowane według klucza.
  5. Ciągi znaków są wyświetlane po liczbach i sortowane leksykograficznie w kolejności rosnącej. Jeśli kilka elementów podrzędnych ma tę samą wartość dla określonego węzła podrzędnego, są one sortowane leksykograficznie według klucza.
  6. Obiekty są wyświetlane na końcu i sortowane leksykograficznie według klucza w kolejności rosnącej.

OrderByKey

Gdy używasz OrderByKey() do sortowania danych, dane są zwracane w kolejności rosnącej według klucza.

  1. Najpierw są wyświetlane elementy podrzędne z kluczem, który można przeanalizować jako 32-bitową liczbę całkowitą, posortowane w kolejności rosnącej.
  2. Następnie są wyświetlane elementy podrzędne z wartością ciągu znaków jako kluczem, posortowane leksykograficznie w kolejności rosnącej.

OrderByValue

Gdy używasz OrderByValue() , elementy podrzędne są sortowane według ich wartości. Kryteria sortowania są takie same jak w przypadku OrderByChild(), z tym że zamiast wartości określonego klucza podrzędnego używana jest wartość węzła.