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

Ten dokument zawiera podstawowe informacje o pobieraniu danych oraz o sposobach ich porządkowania i filtrowania w Firebase.

Zanim zaczniesz

Upewnij się, że aplikacja jest skonfigurowana i masz dostęp do bazy danych zgodnie z instrukcjami w przewodniku Get Started.

Pobieranie danych

Dane Firebase są pobierane przez jednorazowe wywołanie funkcji GetValue() lub dołączenie do funkcji ValueListener w odniesieniu do FirebaseDatabase. Funkcja nasłuchująca wartości jest wywoływana raz w przypadku początkowego stanu danych i ponownie za każdym razem, gdy dane się zmienią.

Pobieranie obiektu DatabaseReference

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

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

Odczytywanie danych tylko raz

Możesz użyć metody GetValue(), aby jednorazowo odczytać statyczny zrzut zawartości w danym ś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ócony zrzut to null.

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

W tym momencie żądanie zostało wysłane, ale musimy poczekać, aż obiekt Future zostanie ukończony, zanim będziemy mogli odczytać wartość. Gry zwykle działają w pętli i są mniej oparte na wywołaniach zwrotnych niż inne aplikacje, dlatego zwykle sprawdzasz, czy zostały ukończone.

  // 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 o sprawdzaniu błędów i sposobach określania, kiedy wynik jest gotowy, znajdziesz w dokumentacji firebase::Future.

Nasłuchiwanie zdarzeń

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

ValueListener klasa bazowa

Oddzwanianie Typowe zastosowanie
OnValueChanged Odczytywanie i nasłuchiwanie zmian w całej zawartości ścieżki.

OnChildListener klasa bazowa

OnChildAdded pobierać listy elementów lub nasłuchiwać dodawania elementów do listy; Sugerowane użycie z OnChildChanged i OnChildRemoved do monitorowania zmian na listach.
OnChildChanged nasłuchiwanie zmian w elementach listy; Używaj z elementami OnChildAdded i OnChildRemoved, aby monitorować zmiany na listach.
OnChildRemoved Nasłuchiwanie elementów usuwanych z listy. Używaj z elementami OnChildAdded i OnChildChanged, aby monitorować zmiany na listach.
OnChildMoved Nasłuchiwanie zmian kolejności elementów na liście numerowanej. OnChildMoved wywołania zwrotne zawsze następują po OnChildChanged wywołaniach zwrotnych z powodu zmiany kolejności elementów (zgodnie z bieżącą metodą sortowania).

Klasa ValueListener

Za pomocą OnValueChangedwywołań zwrotnych możesz subskrybować zmiany w treściach w określonej ścieżce. To wywołanie zwrotne jest wywoływane raz po dołączeniu odbiornika i ponownie za każdym razem, gdy zmienią się dane, w tym dane dzieci. Funkcja zwrotna otrzymuje migawkę zawierającą wszystkie dane w tej lokalizacji, w tym dane podrzędne. Jeśli nie ma danych, zwrócony zrzut to null.

Poniższy przykład pokazuje, jak gra pobiera wyniki z tabeli wynikó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&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

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

W tym przykładzie metoda OnCancelled jest też zastępowana, 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. Symbol database::Error wskaże przyczynę niepowodzenia.

Klasa ChildListener

Zdarzenia dotyczące dzieci są wywoływane w odpowiedzi na określone operacje wykonywane na dzieciach węzła, takie jak dodanie nowego dziecka za pomocą metody PushChild() lub zaktualizowanie dziecka za pomocą metody UpdateChildren(). Każda z tych opcji może być przydatna do nasłuchiwania zmian w określonym węźle w bazie danych. Na przykład gra może używać tych metod razem, aby monitorować aktywność w komentarzach do 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);

Funkcja zwrotna OnChildAdded jest zwykle używana do pobierania listy elementów z bazy danych Firebase. Wywołanie zwrotne OnChildAdded jest wywoływane 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. Do odbiorcy przekazywany jest zrzut zawierający dane nowego elementu podrzędnego.

Wywołanie zwrotne OnChildChanged 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 on zwykle używany w połączeniu z wywołaniami OnChildAdded i OnChildRemoved w celu reagowania na zmiany na liście elementów. Zrzut przekazywany do odbiorcy zawiera zaktualizowane dane elementu podrzędnego.

Wywołanie zwrotne OnChildRemoved jest wywoływane, gdy zostanie usunięte bezpośrednie dziecko. Zwykle jest używana w połączeniu z wywołaniami zwrotnymi OnChildAdded i OnChildChanged. Migawka przekazywana do wywołania zwrotnego zawiera dane usuniętego elementu podrzędnego.

Wywołanie zwrotne OnChildMoved jest wywoływane za każdym razem, gdy wywołanie OnChildChanged jest wywoływane przez aktualizację, która powoduje zmianę kolejności elementów podrzędnych. Jest ona używana w przypadku danych uporządkowanych za pomocą funkcji 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 też filtrować posortowane wyniki, aby wyświetlić określoną liczbę wyników lub zakres kluczy lub wartości.

Sortowanie danych

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

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

Możesz używać tylko jednej metody sortowania naraz. Wielokrotne wywoływanie metody sortowania w tym samym zapytaniu powoduje błąd.

Poniższy przykład pokazuje, jak zasubskrybować tablicę wyników z wynikami uporządkowanymi 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 firebase::Query, który w połączeniu z ValueListener synchronizuje klienta z tablicą wyników w bazie danych, uporządkowaną według wyniku każdego wpisu. Więcej informacji o skutecznym strukturyzowaniu danych znajdziesz w artykule Strukturyzowanie bazy danych.

Wywołanie metody OrderByChild() określa klucz podrzędny, według którego mają być uporządkowane wyniki. W tym przypadku wyniki są sortowane według wartości "score"w każdym elemencie podrzędnym. Więcej informacji o kolejności innych typów danych znajdziesz w artykule Kolejność danych z zapytania.

Filtrowanie danych

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

Metoda Wykorzystanie
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() Zwraca elementy o wartości większej lub równej podanemu kluczowi lub wartości w zależności od wybranej metody sortowania.
EndAt() Zwraca produkty o wartości klucza lub wartości mniejszej lub równej określonej wartości, w zależności od wybranej metody sortowania.
EqualTo() Zwraca elementy równe podanemu kluczowi lub wartości w zależności od wybranej metody sortowania.

W przeciwieństwie do metod sortowania możesz łączyć wiele 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 zwraca tylko 1 wynik, migawka jest listą, która zawiera tylko 1 element.

Ograniczanie liczby wyników

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

W miarę zmian w produktach otrzymujesz OnChildAdded wywołania zwrotne dotyczące produktów, które pojawiają się w zapytaniu, i OnChildRemoved wywołania zwrotne dotyczące produktów, które z niego znikają, 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.

Filtrowanie według klucza lub wartości

Możesz używać symboli StartAt(), EndAt() i EqualTo(), aby wybierać dowolne punkty początkowe, końcowe i równoważne w zapytaniach. Może to być przydatne w przypadku stronicowania danych lub wyszukiwania elementów podrzędnych o określonej wartości.

Sposób uporządkowania danych zapytania

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

OrderByChild

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

  1. Dzieci z wartością null dla określonego klucza dziecka są wyświetlane jako pierwsze.
  2. Następnie wyświetlane są dzieci 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 wyświetlane są dzieci 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 pojawiają się 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ą w przypadku 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 kilka węzłów podrzędnych ma tę samą wartość, są one porządkowane leksykograficznie według klucza.
  6. Obiekty są umieszczane na końcu i sortowane leksykograficznie według klucza w kolejności rosnącej.

OrderByKey

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

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

OrderByValue

W przypadku korzystania z OrderByValue() dzieci są uporządkowane według 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.

Następne kroki