Pobieranie danych za pomocą Bazy danych czasu rzeczywistego Firebase dla C++

W tym dokumencie znajdziesz podstawowe informacje o pobieraniu danych oraz ich sortowaniu i filtrowaniu.

Zanim zaczniesz

Upewnij się, że skonfigurowałaś/skonfigurowałeś aplikację i masz dostęp do bazy danych zgodnie z instrukcjami podanymi w przewodniku Get Started.

Pobieranie danych

Dane Firebase są pobierane przez jednorazowe wywołanie funkcji GetValue() lub przez dołączenie do funkcji ValueListener odwołania FirebaseDatabase. Listener wartości jest wywoływany raz w przypadku początkowego stanu danych i ponownie za każdym razem, gdy dane ulegną zmianie.

Pobieranie obiektu DatabaseReference

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

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

odczytywanie danych raz;

Aby odczytać statyczny zrzut treści w danym miejscu, możesz użyć metody GetValue(). Wynik zadania będzie zawierać migawkę ze wszystkimi danymi w tej lokalizacji, w tym danymi podrzędnymi. Jeśli nie ma żadnych danych, zwrócony zostanie podany fragment kodu null.

  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").GetValue();

W momencie wysłania żądania musimy poczekać na zakończenie działania funkcji Future, aby odczytać wartość. Gry zwykle działają w pętli i w większym stopniu niż inne aplikacje korzystają z wyzwań zwrotnych, dlatego zwykle używają metody poll.

  // 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 podstawową kontrolę błędów. Więcej informacji o tej kontroli oraz o sposobach określania, kiedy wynik jest gotowy, znajdziesz w dokumentacji firebase::Future.

Nasłuchiwanie zdarzeń

Możesz dodać odbiorców, którzy będą subskrybować zmiany w danych:

ValueListener klasa podstawowa

Oddzwanianie Typowe zastosowanie
OnValueChanged czytać i słuchać zmian w całej zawartości ścieżki;

OnChildListener klasa podstawowa

OnChildAdded pobierać listy elementów lub słuchać dodanych elementów na liście; Sugerowane użycie z elementami OnChildChangedOnChildRemoved do monitorowania zmian w listach.
OnChildChanged Słuchaj zmian elementów na liście. Używaj elementów OnChildAdded i OnChildRemoved, aby monitorować zmiany w listach.
OnChildRemoved Słuchaj, czy elementy są usuwane z listy. Używaj elementów OnChildAdded i OnChildChanged, aby monitorować zmiany w listach.
OnChildMoved Słuchaj zmian kolejności elementów na liście uporządkowanej. Wywołania zwrotne OnChildMoved zawsze następują po wywołaniach OnChildChanged, ponieważ kolejność produktów może się zmieniać (w zależności od bieżącej metody sortowania).

Klasa ValueListener

Aby subskrybować zmiany treści na danej ścieżce, możesz użyć wywołań zwrotnych OnValueChanged. Ten wywołanie zwrotne jest wywoływane raz, gdy listener zostanie dołączony, oraz za każdym razem, gdy zmienią się dane, w tym elementy podrzędne. Do funkcji wywołania zwrotnego przekazywany jest zrzut zawierający wszystkie dane w danej lokalizacji, w tym dane podrzędne. Jeśli nie ma żadnych danych, zwracany jest obraz null.

Ten przykład pokazuje grę, która pobiera z bazy danych wyniki z tablicy liderów:

  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&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

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

W tym przykładzie metoda OnCancelled jest również zastąpiona, aby sprawdzić, czy odczyt został anulowany. Na przykład odczyt może zostać anulowany, jeśli klient nie ma uprawnień do odczytu z lokalizacji bazy danych Firebase. database::Error wskazuje, dlaczego wystąpił błąd.

Klasa ChildListener

Zdarzenia podrzędne są wywoływane w odpowiedzi na określone operacje wykonywane na podrzędnych węzłach, np. dodanie nowego podrzędnego za pomocą metody PushChild() lub zaktualizowanie podrzędnego za pomocą metody UpdateChildren(). Każdy z nich może być przydatny do monitorowania zmian w konkretnym węźle w bazie danych. Na przykład gra może używać tych metod razem, aby monitorować aktywność 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&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

Zwykle funkcja zwracana przez wywołanie zwrotne OnChildAdded służy do pobierania listy elementów z bazy danych Firebase. Funkcja OnChildAdded jest wywoływana raz dla każdego istniejącego elementu podrzędnego, a potem za każdym razem, gdy do określonej ścieżki zostanie dodany nowy element podrzędny. Listenerowi przekazywany jest migawkowy widok zawierający dane nowego elementu podrzędnego.

Funkcja OnChildChanged jest wywoływana za każdym razem, gdy nastąpi zmiana węzła podrzędnego. Obejmuje to wszelkie modyfikacje potomków węzła podrzędnego. Jest ona zwykle używana w połączeniu z wywołaniami OnChildAddedOnChildRemoved, aby reagować na zmiany w liście elementów. Zrzut przekazany do listenera zawiera zaktualizowane dane dotyczące obiektu podrzędnego.

Funkcja OnChildRemoved jest wywoływana, gdy następuje usunięcie bezpośredniego podrzędnego. Jest ona zwykle używana w połączeniu z funkcjami zwrotnymi OnChildAddedOnChildChanged. Zrzut przesłany do funkcji zwracającej dane zawiera dane dotyczące usuniętego elementu podrzędnego.

Funkcja OnChildMoved jest wywoływana za każdym razem, gdy wywołanie OnChildChanged jest wywołane przez aktualizację, która powoduje zmianę kolejności podrzędnego. Jest on używany w przypadku danych uporządkowanych za pomocą funkcji OrderByChild lub OrderByValue.

Sortowanie i filtrowanie danych

Aby pobrać dane posortowane według klucza, wartości lub wartości podrzędnego, możesz użyć klasy Realtime Database Query. Możesz też ograniczyć liczbę wyników do określonej liczby lub do określonego zakresu kluczy bądź wartości.

Sortowanie danych

Aby pobrać posortowane dane, najpierw określ jedną z metod sortowania, która określi sposób sortowania wyników:

Metoda Wykorzystanie
OrderByChild() Porządkuj wyniki według wartości określonego klucza podrzędnego.
OrderByKey() Uporządkuj wyniki według kluczy podrzędnych.
OrderByValue() Porządkuj wyniki według wartości elementów podrzędnych.

Możesz użyć tylko jednej metody sortowania naraz. Wywołanie metody sortowania kilka razy w tym samym zapytaniu powoduje błąd.

Ten przykład pokazuje, jak można subskrybować tabelę wyników z rankingiem 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.

Określa ona obiekt firebase::Query, który w połączeniu z ValueListener synchronizuje klienta z listą liderów w bazie danych, posortowaną według wyniku każdego wpisu. Więcej informacji o skutecznym porządkowaniu danych znajdziesz w artykule Uporządkuj bazę danych.

Wywołanie metody OrderByChild() określa klucz podrzędny, według którego mają być posortowane wyniki. W tym przypadku wyniki są sortowane według wartości atrybutu "score" w każdym podrzędnym. Więcej informacji o porządkowaniu innych typów danych znajdziesz w artykule Porządkowanie danych zapytań.

Filtrowanie danych

Aby filtrować dane, podczas tworzenia zapytania możesz połączyć dowolną metodę limit lub range z metodą order-by.

Metoda Wykorzystanie
LimitToFirst() Określa maksymalną liczbę elementów do zwrócenia z początku uporządkowanej listy wyników.
LimitToLast() Określa maksymalną liczbę elementów do zwrócenia z końca posortowanej listy wyników.
StartAt() Zwraca elementy, których wartość jest większa lub równa określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
EndAt() Zwraca elementy, które są mniejsze lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
EqualTo() Zwraca elementy o wartości określonej w kluczu lub wartości w zależności od wybranej metody sortowania.

W przeciwieństwie do metod porządkowania według kolumny możesz łączyć wiele funkcji limit i zakres. Możesz np. połączyć metody StartAt()EndAt(), aby ograniczyć wyniki do określonego zakresu wartości.

Nawet wtedy, gdy zapytanie ma tylko 1 pasujący element, snapshot jest nadal listą, ale zawiera tylko 1 element.

Ograniczanie liczby wyników

Aby ustawić maksymalną liczbę elementów podrzędnych, które mają być synchronizowane w przypadku danego wywołania zwrotnego, możesz użyć metod LimitToFirst()LimitToLast(). Jeśli np. użyjesz funkcji LimitToFirst(), aby ustawić limit na 100, początkowo otrzymasz tylko do 100 wywołań funkcji OnChildAdded. Jeśli w bazie danych Firebase masz mniej niż 100 elementów, dla każdego z nich zostanie wywołana funkcja OnChildAdded.

Gdy elementy się zmieniają, otrzymujesz OnChildAdded wywołania zwrotne dla elementów, które wchodzą do zapytania, oraz OnChildRemoved wywołania zwrotne 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 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.

Filtrowanie według klucza lub wartości

Za pomocą funkcji StartAt(), EndAt()EqualTo() możesz wybrać dowolne punkty początkowe, końcowe i równoważne w zapytaniach. Może to być przydatne do przewijania danych lub znajdowania elementów podrzędnych o określonej wartości.

Sposób sortowania danych zapytania

W tej sekcji wyjaśniamy, jak dane są sortowane według każdej z metod sortowania w klasie Query.

OrderByChild

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

  1. Najpierw są wyświetlane elementy podrzędne, dla których wartość atrybutu podrzędnego null jest równa null.
  2. Następnie podawane są elementy podrzędne, dla których wartość określonego klucza podrzędnego to false. Jeśli wiele elementów podrzędnych ma wartość false, są one sortowane alfabetycznie według klucza.
  3. Następnie podawane są elementy podrzędne, dla których wartość określonego klucza podrzędnego to true. Jeśli kilka elementów podrzędnych ma wartość true, są one sortowane alfabetycznie według klucza.
  4. Następnie pojawiają się elementy z wartością liczbową, posortowane w kolejności rosnącej. Jeśli wiele elementów podrzędnych ma tę samą wartość numeryczną w przypadku określonego węzła podrzędnego, są one sortowane według klucza.
  5. Ciągi tekstowe występują po liczbach i są sortowane alfabetycznie w kolejności rosnącej. Jeśli wiele elementów podrzędnych ma tę samą wartość w wybranym węźle podrzędnym, są one uporządkowane alfabetycznie według klucza.
  6. Obiekty znajdują się na końcu i są posortowane leksykograficznie według klucza w kolejności rosnącej.

OrderByKey

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

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

OrderByValue

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

Następne kroki