Pobieranie danych za pomocą bazy danych Firebase Realtime Database dla C++

W tym dokumencie opisano podstawy pobierania danych oraz porządkowania i filtrowania danych Firebase.

Zanim zaczniesz

Upewnij się, że aplikacja została skonfigurowana i że masz dostęp do bazy danych zgodnie z opisem w przewodniku Get Started .

Pobieranie danych

Dane Firebase są pobierane przez jednorazowe wywołanie metody GetValue() lub dołączenie do ValueListener w odniesieniu do FirebaseDatabase . Nasłuchiwanie wartości jest wywoływane raz dla stanu początkowego danych i ponownie za każdym razem, gdy dane się zmieniają.

Uzyskaj odniesienie 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();

Przeczytaj dane raz

Możesz użyć metody GetValue() , aby jednorazowo odczytać statyczną migawkę zawartości w danej ścieżce. Wynik zadania będzie zawierał migawkę zawierającą wszystkie dane w tej lokalizacji, w tym dane podrzędne. Jeśli nie ma danych, zwrócona migawka ma null .

  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("Leaders").GetValue();

W tym momencie żądanie zostało złożone, ale musimy poczekać, aż przyszłość się zakończy, zanim będziemy mogli odczytać wartość. Ponieważ gry zazwyczaj działają w pętli i w mniejszym stopniu wymagają wywołań zwrotnych niż inne aplikacje, zazwyczaj będziesz odpytywać o ukończenie.

  // In the game loop that polls for the result...

  if (result.status() != firebase::kFutureStatusPending) {
    if (result.status() != firebase::kFutureStatusComplete) {
      LogMessage("ERROR: GetValue() returned an invalid result.");
      // Handle the error...
    } else if (result.error() != firebase::database::kErrorNone) {
      LogMessage("ERROR: GetValue() returned error %d: %s", result.error(),
                 result.error_message());
      // Handle the error...
    } else {
      firebase::database::DataSnapshot snapshot = result.result();
      // Do something with the snapshot...
    }
  }

Pokazuje to podstawowe sprawdzanie błędów. Więcej informacji na temat sprawdzania błędów i sposobów określania, kiedy wynik będzie gotowy, można znaleźć w dokumentacji Firebase::Future .

Słuchaj wydarzeń

Możesz dodać słuchaczy, aby subskrybować zmiany danych:

Klasa bazowa ValueListener

Oddzwonić Typowe użycie
OnValueChanged Czytaj i słuchaj zmian w całej zawartości ścieżki.

Klasa bazowa OnChildListener

OnChildAdded Pobieraj listy elementów lub słuchaj dodatków do listy elementów. Sugerowane użycie z OnChildChanged i OnChildRemoved do monitorowania zmian na listach.
OnChildChanged Słuchaj zmian w elementach na liście. Użyj z OnChildAdded i OnChildRemoved , aby monitorować zmiany na listach.
OnChildRemoved Posłuchaj, czy elementy są usuwane z listy. Używaj z OnChildAdded i OnChildChanged do monitorowania zmian na listach.
OnChildMoved Słuchaj zmian w kolejności elementów na uporządkowanej liście. Wywołania zwrotne OnChildMoved zawsze następują po wywołaniach zwrotnych OnChildChanged ze względu na zmianę kolejności elementu (w oparciu o bieżącą metodę zamawiania).

Klasa ValueListener

Możesz użyć wywołań zwrotnych OnValueChanged , aby subskrybować zmiany zawartości w danej ścieżce. To wywołanie zwrotne jest wyzwalane raz, gdy słuchacz jest podłączony, i ponownie za każdym razem, gdy zmieniają się dane, w tym dzieci. Do wywołania zwrotnego przekazywana jest migawka zawierająca wszystkie dane w tej lokalizacji, w tym dane podrzędne. Jeśli nie ma danych, zwrócona migawka ma null .

Poniższy przykład ilustruje grę pobierającą wyniki tabeli liderów z bazy danych:

  class LeadersValueListener : public firebase::database::ValueListener {
   public:
    void OnValueChanged(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: LeadersValueListener canceled: %d: %s", error_code,
                 error_message);
    }
  };

  // Elsewhere in the code...

  LeadersValueListener* listener = new LeadersValueListener();
  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

Wynik Future&ltDataSnapshot&gt zawiera dane w określonej lokalizacji w bazie danych w momencie zdarzenia. Wywołanie value() na migawce zwraca Variant reprezentujący dane.

W tym przykładzie metoda OnCancelled jest również zastępowana, aby sprawdzić, czy odczyt został anulowany. Na przykład odczyt można anulować, jeśli klient nie ma uprawnień do odczytu z lokalizacji bazy danych Firebase. database::Error wskaże przyczynę wystąpienia błędu.

Klasa ChildListener

Zdarzenia podrzędne są wywoływane w odpowiedzi na określone operacje, które mają miejsce na elementach podrzędnych węzła w wyniku operacji, takiej jak dodanie nowego elementu podrzędnego za pomocą metody PushChild() lub aktualizacja elementu podrzędnego za pomocą metody UpdateChildren() . Każdy z nich razem może być przydatny do nasłuchiwania zmian w określonym węźle w bazie danych. Na przykład gra może używać tych metod łącznie do monitorowania aktywności w komentarzach sesji gry, jak pokazano poniżej:

  class SessionCommentsChildListener : public firebase::database::ChildListener {
   public:
    void OnChildAdded(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildChanged(const firebase::database::DataSnapshot& snapshot,
                        const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildRemoved(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot ...
    }
    void OnChildMoved(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: SessionCommentsChildListener canceled: %d: %s",
                 error_code, error_message);
    }
  };

  // elsewhere ....

  SessionCommentsChildListener* listener = new SessionCommentsChildListener();
  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

Wywołanie zwrotne OnChildAdded jest zwykle używane do pobierania listy elementów w bazie danych Firebase. Wywołanie zwrotne OnChildAdded jest wywoływane raz dla każdego istniejącego elementu podrzędnego, a następnie ponownie za każdym razem, gdy do określonej ścieżki dodawane jest nowe dziecko. Do słuchacza przekazywana jest migawka zawierająca dane nowego dziecka.

Wywołanie zwrotne OnChildChanged jest wywoływane za każdym razem, gdy modyfikuje się węzeł podrzędny. Obejmuje to wszelkie modyfikacje elementów podrzędnych węzła podrzędnego. Zwykle jest używany w połączeniu z wywołaniami OnChildAdded i OnChildRemoved w celu reagowania na zmiany na liście elementów. Migawka przekazana do odbiornika zawiera zaktualizowane dane elementu podrzędnego.

Wywołanie zwrotne OnChildRemoved jest wyzwalane w przypadku usunięcia bezpośredniego elementu podrzędnego. Zwykle jest używany w połączeniu z wywołaniami zwrotnymi OnChildAdded i OnChildChanged . Migawka przekazana do wywołania zwrotnego zawiera dane usuniętego elementu podrzędnego.

Wywołanie zwrotne OnChildMoved jest wyzwalane za każdym razem, gdy wywołanie OnChildChanged zostanie wywołane przez aktualizację, która powoduje zmianę kolejności elementu podrzędnego. Jest używany z danymi uporządkowanymi za pomocą OrderByChild lub OrderByValue .

Sortowanie i filtrowanie danych

Możesz użyć klasy Realtime Database Query , aby pobrać dane posortowane według klucza, wartości lub wartości elementu podrzędnego. Możesz także filtrować posortowane wyniki według określonej liczby wyników lub zakresu kluczy lub wartości.

Sortuj dane

Aby pobrać posortowane dane, zacznij od określenia jednej z metod porządkowania, aby określić sposób uporządkowania wyników:

metoda Stosowanie
OrderByChild() Uporządkuj wyniki według wartości określonego klucza podrzędnego.
OrderByKey() Uporządkuj wyniki według kluczy podrzędnych.
OrderByValue() Uporządkuj wyniki według wartości podrzędnych.

Możesz użyć tylko jednej metody sortowania na raz. Wielokrotne wywołanie metody sortowania według tego samego zapytania powoduje błąd.

Poniższy przykład ilustruje, jak można zasubskrybować tabelę wyników uporządkowaną według wyniku.

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score");

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

Definiuje to firebase::Query , które w połączeniu z ValueListener synchronizuje klienta z tabelą liderów w bazie danych, uporządkowaną według wyniku każdego wpisu. Więcej informacji na temat efektywnego strukturyzacji danych można znaleźć w artykule Struktura bazy danych .

Wywołanie metody OrderByChild() określa klucz podrzędny, według którego mają zostać uporządkowane wyniki. W tym przypadku wyniki są sortowane według wartości "score" u każdego dziecka. Więcej informacji na temat porządkowania innych typów danych można znaleźć w artykule Jak uporządkowane są dane zapytań .

Filtrowanie danych

Aby filtrować dane, podczas konstruowania zapytania możesz połączyć dowolną metodę limitu lub zakresu z metodą porządkowania.

metoda Stosowanie
LimitToFirst() Ustawia maksymalną liczbę elementów do zwrócenia od początku uporządkowanej listy wyników.
LimitToLast() Ustawia maksymalną liczbę elementów zwracanych z końca uporządkowanej listy wyników.
StartAt() Zwracaj elementy większe lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
EndAt() Zwróć produkty mniejsze lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody zamawiania.
EqualTo() Zwróć pozycje równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.

W przeciwieństwie do metod sortowania, można łączyć wiele funkcji limitów lub zakresów. Można na przykład połączyć metody StartAt() i EndAt() , aby ograniczyć wyniki do określonego zakresu wartości.

Nawet jeśli zapytanie odpowiada tylko jednemu dopasowaniu, zrzut ekranu nadal jest listą; zawiera tylko jeden element.

Ogranicz liczbę wyników

Możesz użyć metod LimitToFirst() i LimitToLast() , aby ustawić maksymalną liczbę dzieci, które mają być synchronizowane dla danego wywołania zwrotnego. Na przykład, jeśli użyjesz LimitToFirst() do ustawienia limitu na 100, początkowo otrzymasz tylko do 100 wywołań zwrotnych OnChildAdded . Jeśli w bazie danych Firebase przechowywanych jest mniej niż 100 elementów, dla każdego elementu uruchamiane jest wywołanie zwrotne OnChildAdded .

Gdy elementy się zmieniają, otrzymujesz wywołania OnChildAdded dla elementów, które wchodzą do zapytania, oraz wywołania zwrotne OnChildRemoved dla elementów, które z niego wypadają, tak że łączna liczba pozostaje na poziomie 100.

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

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score").LimitToLast(1);

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

Filtruj według klucza lub wartości

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

Sposób uporządkowania danych zapytania

W tej sekcji wyjaśniono, w jaki sposób dane są sortowane według każdej metody porządkowania w klasie Query .

OrderByChild

W przypadku korzystania z OrderByChild() dane zawierające określony klucz podrzędny są porządkowane w następujący sposób:

  1. Dzieci z wartością null dla określonego klucza podrzędnego są traktowane jako pierwsze.
  2. Następne są dzieci z wartością false dla określonego klucza podrzędnego. Jeśli wiele elementów podrzędnych ma wartość false , są one sortowane leksykograficznie według klucza.
  3. Następne są dzieci z wartością true dla określonego klucza podrzędnego. Jeśli wiele elementów podrzędnych ma wartość true , są one sortowane leksykograficznie według klucza.
  4. Następne są dzieci z wartością liczbową, posortowane w kolejności rosnącej. Jeśli wiele 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 występują po liczbach i są sortowane leksykograficznie w kolejności rosnącej. Jeśli wiele elementów podrzędnych ma tę samą wartość dla określonego węzła podrzędnego, są one uporządkowane leksykograficznie według klucza.
  6. Obiekty są umieszczane na końcu i są sortowane leksykograficznie według kluczy w kolejności rosnącej.

OrderByKey

Podczas sortowania danych za pomocą OrderByKey() dane są zwracane w kolejności rosnącej według klucza.

  1. Na pierwszym miejscu znajdują się dzieci z kluczem, który można przeanalizować jako 32-bitową liczbę całkowitą, posortowane w kolejności rosnącej.
  2. Następne są dzieci, których kluczem jest wartość ciągu, posortowane leksykograficznie w kolejności rosnącej.

OrderByValue

Podczas korzystania z OrderByValue() elementy podrzędne są porządkowane według ich wartości. Kryteria porządkowania są takie same jak w przypadku OrderByChild() , z tą różnicą, że zamiast wartości określonego klucza podrzędnego używana jest wartość węzła.

Następne kroki