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

W tym dokumencie znajdziesz podstawowe informacje o pobieraniu danych oraz sposobie ich porządkowania i filtrowania.

Zanim zaczniesz

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

Pobieram dane

Dane Firebase są pobierane przez jednorazowe wywołanie GetValue() lub załączając je do ValueListener w odniesieniu FirebaseDatabase. Detektor wartości jest wywoływany raz dla początkowego stanu danych i ponownie przy każdej zmianie danych.

Pobieranie odniesienia 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();

Odczytaj dane raz

Metoda GetValue() pozwala jednorazowo odczytać statyczny zrzut zawartości w danej ścieżce. Wynik zadania będzie zawierał zrzut zawierający wszystkie dane w tej lokalizacji, w tym dane podrzędne. Jeśli nie ma danych, zwrócony zrzut ma wartość null.

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

Otrzymaliśmy już w ten sposób prośbę, ale musimy poczekać na zakończenie działania w przyszłości, zanim będziemy mogli odczytać wartość. Gry zwykle działają w pętli i są mniej wywoływane niż inne aplikacje, dlatego sondowanie jest zwykle przeprowadzane w celu ukończenia.

  // 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...
    }
  }

Tutaj znajdziesz podstawowe informacje o sprawdzaniu błędów. Więcej informacji o sprawdzaniu błędów i sposobach określania, kiedy wynik będzie gotowy, znajdziesz w dokumentacji firebase::Future.

Nasłuchiwanie zdarzeń

Możesz dodać detektorów, aby subskrybować zmiany w danych:

ValueListener klasa bazowa

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

OnChildListener klasa bazowa

OnChildAdded Pobieranie list elementów lub słuchanie, czy dodano elementy do listy. Sugerowane użycie z funkcjami OnChildChanged i OnChildRemoved do monitorowania zmian na listach.
OnChildChanged Wykrywaj zmiany wprowadzone w elementach na liście. Używaj z OnChildAdded i OnChildRemoved do monitorowania zmian na listach.
OnChildRemoved Nasłuchuj elementów usuwanych z listy. Używaj z OnChildAdded i OnChildChanged do monitorowania zmian na listach.
OnChildMoved Wykrywaj zmiany kolejności elementów na liście uporządkowanej. Wywołania zwrotne OnChildMoved zawsze występują po wywołaniach zwrotnych OnChildChanged z powodu zmiany kolejności produktu (na podstawie bieżącej metody sortowania).

Klasa ValueListener

Za pomocą wywołań zwrotnych OnValueChanged możesz zasubskrybować zmiany treści na danej ścieżce. Wywołanie zwrotne jest wywoływane raz po podłączeniu detektora i ponownie za każdym razem, gdy dane, w tym elementy podrzędne, zostaną zmienione. Wywołanie zwrotne jest przekazywane do zrzutu zawierającego wszystkie dane w danej lokalizacji, w tym dane podrzędne. Jeśli nie ma danych, zwrócony zrzut ma wartość null.

Ten przykład przedstawia grę, która pobiera wyniki 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<firebase::database::DataSnapshot> 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() w zrzucie 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żna anulować, jeśli klient nie ma uprawnień do odczytu lokalizacji bazy danych Firebase. W polu database::Error znajdziesz informację o przyczynie błędu.

Klasa ChildListener

Zdarzenia podrzędne są wywoływane w odpowiedzi na określone operacje wykonywane na elementach podrzędnych węzła w wyniku operacji, np. dodania nowego elementu podrzędnego za pomocą metody PushChild() lub aktualizacji elementu podrzędnego za pomocą metody UpdateChildren(). Każdy z tych elementów może być przydatny do nasłuchiwania zmian w konkretnym węźle w bazie danych. Na przykład gra może używać tych metod do monitorowania aktywności 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<firebase::database::DataSnapshot> result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

Wywołanie zwrotne OnChildAdded jest zwykle używane 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 następnie za każdym razem, gdy do wskazanej ścieżki dodajesz nowy element podrzędny. Detektor przekazuje zrzut zawierający dane nowego elementu podrzędnego.

Wywołanie zwrotne OnChildChanged jest wywoływane za każdym razem, gdy węzeł podrzędny jest modyfikowany. Obejmuje to wszelkie modyfikacje elementów podrzędnych węzła podrzędnego. Jest zwykle używany w połączeniu z wywołaniami OnChildAdded i OnChildRemoved w odpowiedzi na zmiany na liście elementów. Zrzut przekazany do detektora zawiera zaktualizowane dane elementu podrzędnego.

Wywołanie zwrotne OnChildRemoved jest wyzwalane po usunięciu natychmiastowego elementu podrzędnego. Zwykle jest używany w połączeniu z wywołaniami OnChildAdded i OnChildChanged. Zrzut przekazany do wywołania zwrotnego zawiera dane usuniętego elementu podrzędnego.

Wywołanie zwrotne OnChildMoved jest wywoływane za każdym razem, gdy aktualizacja powoduje zmianę kolejności elementu podrzędnego w elemencie OnChildChanged. Jest używany z danymi uporządkowanych według: OrderByChild lub OrderByValue.

Sortowanie i filtrowanie danych

Za pomocą klasy Query Bazy danych czasu rzeczywistego możesz pobrać dane posortowane według klucza, wartości lub wartości elementu podrzędnego. Możesz też filtrować posortowany wynik według określonej liczby wyników lub zakresu kluczy bądź wartości.

Sortowanie danych

Aby pobrać posortowane dane, zacznij od określenia jednej z metod ustalania kolejności wyników:

Metoda Wykorzystanie
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.

W danym momencie możesz używać tylko jednej metody sortowania. Wielokrotne wywołanie metody „order by by” w tym samym zapytaniu powoduje błąd.

Ten przykład pokazuje, jak zasubskrybować tabelę wyników uporządkowanych 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 funkcję firebase::Query, która w połączeniu z funkcją ValueListener synchronizuje klienta z tabelą wyników w bazie danych w kolejności uporządkowanej według wyniku każdego wpisu. Więcej informacji o efektywnym strukturze 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 wartości "score" w każdym elemencie podrzędnym. Więcej informacji o kolejności innych typów danych znajdziesz w sekcji Informacje o kolejności danych w zapytaniach.

Filtrowanie danych

Aby filtrować dane, podczas tworzenia zapytania możesz połączyć dowolne metody limitów lub zakresów z metodą porządkowania.

Metoda Wykorzystanie
LimitToFirst() Określa maksymalną liczbę elementów do zwrócenia od początku uporządkowanej listy wyników.
LimitToLast() Określa maksymalną liczbę elementów do zwrócenia na końcu 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 bądź 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 według kolejności można łączyć wiele funkcji ograniczeń lub zakresu. Możesz np. łączyć metody StartAt() i EndAt(), aby ograniczyć wyniki do określonego zakresu wartości.

Nawet wtedy, gdy dla zapytania występuje tylko jedno dopasowanie, zrzut nadal jest listą, zawiera tylko 1 element.

Ogranicz liczbę 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(), aby ustawić limit 100, początkowo otrzymasz maksymalnie 100 wywołań zwrotnych OnChildAdded. Jeśli w bazie danych Firebase masz mniej niż 100 elementów, dla każdego z nich uruchamia się wywołanie zwrotne OnChildAdded.

Wraz ze zmianą elementów otrzymujesz wywołania zwrotne OnChildAdded dla tych, które wpiszą zapytanie, oraz OnChildRemoved wywołań zwrotnych dla elementów, które z nich nie korzystają. Dzięki temu łączna liczba pozostaje na 100.

Na przykład poniższy kod zwraca najlepszy wynik z tabeli 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

Za pomocą parametrów StartAt(), EndAt() i EqualTo() możesz wybierać dla zapytań dowolny punkt początkowy, końcowy i równoważny. Przydaje się to przy dzieleniu danych na strony lub wyszukiwaniu elementów z elementami podrzędnymi, które mają określoną wartość.

Sposób porządkowania danych zapytań

W tej sekcji wyjaśniamy, jak dane są sortowane według metody w klasie Query.

OrderByChild

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

  1. Jako pierwsze wyświetlają się elementy podrzędne z wartością null określonego klucza podrzędnego.
  2. Następne są elementy podrzędne z wartością false określonego klucza podrzędnego. Jeśli kilka elementów podrzędnych ma wartość false, są one sortowane leksykograficznie według klucza.
  3. Następne są elementy podrzędne z wartością true określonego klucza podrzędnego. Jeśli kilka elementów podrzędnych ma wartość true, są one sortowane leksykograficznie według klucza.
  4. Następne są elementy podrzędne z wartością liczbową, posortowane w kolejności rosnącej. Jeśli wiele elementów podrzędnych ma tę samą wartość liczbową określonego węzła podrzędnego, są one sortowane według klucza.
  5. Ciągi znaków znajdują się po liczbach i są sortowane leksykograficznie w kolejności rosnącej. Jeśli wiele elementów podrzędnych ma tę samą wartość w określonym węźle podrzędnym, są one uporządkowane leksykograficznie według klucza.
  6. Obiekty są na końcu i są sortowane leksykograficznie według klucza w kolejności rosnącej.

OrderByKey

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

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

OrderByValue

Gdy używasz metody OrderByValue(), elementy podrzędne są uporządkowane według wartości. Kryteria sortowania są takie same jak w OrderByChild(), z tą różnicą, że zamiast wartości określonego klucza podrzędnego używana jest wartość węzła.

Następne kroki