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

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

Zanim zaczniesz

Upewnij się, że masz skonfigurowaną aplikację i masz dostęp do bazy danych zgodnie z opisem w przewodniku Get Started .

Pobieranie danych

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

Pobierz DatabaseReference

Aby zapisać dane w bazie danych, potrzebujesz instancji DatabaseReference :

    // Get the root reference location of the database.
    firebase::database::DatabaseReference dbref = database->GetReference();

Odczytaj 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 jest null .

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

W momencie, gdy żądanie zostało wysłane, ale musimy poczekać na zakończenie Future, zanim będziemy mogli odczytać wartość. Ponieważ gry zazwyczaj działają w pętli i są w mniejszym stopniu zależne od wywołań zwrotnych niż inne aplikacje, zazwyczaj będziesz odpytywać o ich 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...
    }
  }

To pokazuje podstawowe sprawdzanie błędów, zobacz firebase::Future Reference, aby uzyskać więcej informacji na temat sprawdzania błędów i sposobów określania, kiedy wynik jest gotowy.

Słuchaj wydarzeń

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

Klasa bazowa ValueListener

Oddzwonić Typowe użycie
OnValueChanged Odczytywanie i nasłuchiwanie 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 pozycji na liście. Używaj z OnChildAdded i OnChildRemoved , aby monitorować zmiany na listach.
OnChildRemoved Słuchaj, czy elementy są usuwane z listy. Używaj z OnChildAdded i OnChildChanged , aby monitorować zmiany na listach.
OnChildMoved Słuchaj zmian 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 (na podstawie bieżącej metody zamawiania według).

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 odbiornik jest podłączony, i ponownie za każdym razem, gdy zmieniają się dane, w tym elementy podrzędne. Wywołanie zwrotne przekazuje migawkę zawierającą wszystkie dane w tej lokalizacji, w tym dane podrzędne. Jeśli nie ma danych, zwrócona migawka jest 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&ltDataSnaphot&gt zawiera dane w określonej lokalizacji w bazie danych w czasie 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ę niepowodzenia.

Klasa ChildListener

Zdarzenia podrzędne są wyzwalane w odpowiedzi na określone operacje, które mają miejsce na elementach podrzędnych węzła z operacji, takich jak dodanie nowego elementu podrzędnego za pomocą metody PushChild() lub zaktualizowanie elementu podrzędnego za pomocą metody UpdateChildren() . Każde z nich razem 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:

  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 zostanie dodany nowy element podrzędny. Odbiornik otrzymuje migawkę zawierającą dane nowego dziecka.

Wywołanie zwrotne OnChildChanged jest wywoływane za każdym razem, gdy modyfikowany jest węzeł podrzędny. Obejmuje to wszelkie modyfikacje potomków 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 dla dziecka.

Wywołanie zwrotne OnChildRemoved jest wyzwalane po usunięciu 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 jest zgłaszane 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 Query do bazy danych czasu rzeczywistego, aby pobrać dane posortowane według klucza, wartości lub wartości elementu podrzędnego. Możesz także filtrować posortowany wynik do 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 w celu określenia kolejności wyników:

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

W danym momencie możesz użyć tylko jednej metody zamawiania według. Wielokrotne wywołanie metody sortowania według w tym samym zapytaniu spowoduje zgłoszenie błędu.

Poniższy przykład pokazuje, 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.

To definiuje firebase::Query , które w połączeniu z ValueListener synchronizuje klienta z rankingiem w bazie danych, uporządkowanym według wyniku każdego wpisu. Więcej informacji na temat efektywnego organizowania 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 takim przypadku wyniki są sortowane według wartości "score" w każdym dziecku. Aby uzyskać więcej informacji na temat porządkowania innych typów danych, zobacz Jak uporządkowane są dane zapytania .

Filtrowanie danych

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

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 do zwrócenia z końca uporządkowanej listy wyników.
StartAt() Zwróć elementy większe lub równe podanemu kluczowi lub wartości w zależności od wybranej metody zamawiania.
EndAt() Zwracaj przedmioty mniejsze lub równe podanemu kluczowi lub wartości, w zależności od wybranej metody zamawiania.
EqualTo() Zwróć elementy równe określonemu kluczowi lub wartości w zależności od wybranej metody zamawiania.

W przeciwieństwie do metod sortowania według, 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 istnieje tylko jedno dopasowanie do zapytania, migawka nadal jest listą; zawiera tylko jeden element.

Ogranicz liczbę wyników

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

Gdy elementy się zmieniają, otrzymujesz wywołania OnChildAdded dla elementów, które wprowadzają zapytanie, i wywołania zwrotne OnChildRemoved dla elementów, które z niego wypadają, dzięki czemu łączna liczba pozostaje na poziomie 100.

Na przykład poniższy kod zwraca najwyższy wynik z tablicy wynikó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

StartAt() , EndAt() i EqualTo() można używać do wybierania dowolnych punktów początkowych, końcowych i równoważnych 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ść.

Jak uporządkowane są dane zapytania

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

OrderByChild

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

  1. Dzieci z wartością null dla określonego klucza podrzędnego są na pierwszym miejscu.
  2. Dzieci z wartością false dla określonego klucza potomnego są następne. Jeśli wiele elementów podrzędnych ma wartość false , są one sortowane leksykograficznie według klucza.
  3. Dzieci z wartością true dla określonego klucza podrzędnego są następne. 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 rosnąco. 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 występują po liczbach i są sortowane leksykograficznie w porządku rosnącym. 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ą na końcu i są sortowane leksykograficznie według klucza w porządku rosnącym.

OrderByKey

Gdy używasz OrderByKey() do sortowania danych, dane są zwracane w porządku rosnącym według klucza.

  1. Dzieci z kluczem, który można przeanalizować jako 32-bitową liczbę całkowitą, są pierwsze, posortowane w porządku rosnącym.
  2. Dzieci z wartością ciągu jako kluczem są następne, posortowane leksykograficznie w porządku rosnącym.

OrderByValue

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

Następne kroki