使用 C++ 適用的 Firebase 即時資料庫擷取資料

本文說明擷取資料的基本概念,以及如何排序及篩選資料 Firebase 資料。

事前準備

確認您已經設定應用程式,並且能存取資料庫 (請參閱下文) Get Started 指南。

正在擷取資料

Firebase 資料是由對 GetValue() 執行一次呼叫的一次性呼叫,或是 附加至 FirebaseDatabase 參照的 ValueListener。這個鍵 系統會呼叫一次接聽程式,以取得資料的初始狀態,並再次呼叫 資料變更。

取得 DatabaseReference

如要將資料寫入資料庫,您需要 DatabaseReference 的執行個體:

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

讀取資料一次

您可以使用 GetValue() 方法讀取 傳回的資訊工作結果會包含快照 ,其中包含該地上的所有資料,包括兒童資料。如果沒有資料, 傳回的快照為 null

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

此時提出要求,但我們必須等待 Future 完成後,我們才能讀取該值由於遊戲通常會以迴圈方式執行,且 相較於其他應用程式,您的應用程式促成的回呼通常減少,一般會輪詢 完成。

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

這裡會顯示一些基本的錯誤檢查 firebase::Future 參考資料 錯誤檢查相關資訊,以及判斷結果何時準備就緒的方法。

接聽事件

您可以新增事件監聽器來訂閱資料變更:

ValueListener 基礎類別

回撥電話 一般用量
OnValueChanged 讀取及監聽路徑完整內容的異動。

OnChildListener 基礎類別

OnChildAdded 擷取項目清單,或監聽附加項目清單。 建議搭配OnChildChangedOnChildRemoved以監控清單變更。
OnChildChanged 監聽清單中項目的變更。與以下項目搭配使用: OnChildAddedOnChildRemoved可監控 對清單做出變更
OnChildRemoved 監聽已從清單中移除的項目。與以下項目搭配使用: OnChildAddedOnChildChanged可監控 對清單做出變更
OnChildMoved 監聽已排序清單中項目順序的變更。 OnChildMoved 回呼一律會遵循 因項目訂單而產生的 OnChildChanged 回呼 (根據目前的訂單處理方式)。

ValueListener 類別

您可以使用 OnValueChanged 回呼來訂閱 特定路徑上的內容這個回呼會在監聽器發生時觸發一次 並在每次資料變更時再次執行 系統會向回呼傳遞一個快照,其中包含該位置的所有資料,包括 子項資料如果沒有資料,則傳回的快照為 null

以下範例示範遊戲擷取排行榜分數 資料庫:

  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);

Future&ltDataSnapshot&gt 結果包含指定位置的資料 加入事件。正在透過快照呼叫 value() 會傳回代表資料的 Variant

在這個範例中,OnCancelled 方法也遭到覆寫,以確認讀取作業沒有 已取消舉例來說,如果用戶端沒有讀取紀錄,系統可取消讀取作業 讀取 Firebase 資料庫位置的權限。database::Error會 指出失敗的原因。

ChildListener 類別

如果容器中發生特定作業, 節點的子項,例如透過 PushChild() 方法或透過 UpdateChildren() 更新的子項 方法。這些組合都適合用來監聽 資料庫內的特定節點舉例來說,遊戲可能會使用以下方法 一起監控遊戲留言中的活動,如下所示:

  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);

OnChildAdded 回呼通常用於擷取 Firebase 資料庫中的項目系統會呼叫 OnChildAdded 回呼一次 而每次將新子新增到 指定的路徑事件監聽器會傳遞含有新子項的快照 資料。

每當修改子節點時,系統就會呼叫 OnChildChanged 回呼。 這也包括對子節點子系所做的任何修改。是 通常會搭配 OnChildAddedOnChildRemoved 使用 呼叫,回應項目清單變更。傳送到 接聽程式包含子項的更新資料。

移除立即子項時,會觸發 OnChildRemoved 回呼。 通常會搭配 OnChildAddedOnChildChanged 回呼。傳遞給回呼的快照包含 移除被移除的孩童資料

OnChildMoved 回呼會在每次 OnChildChanged 時觸發 。是 搭配依 OrderByChildOrderByValue 排序的資料使用。

排序及篩選資料

您可以使用即時資料庫 Query 類別來擷取按照以下條件排序的資料: 索引鍵、值或子項的值你也可以篩選 在特定數量的結果或索引鍵範圍內排序的結果 輕鬆分配獎金

排序資料

如要擷取經過排序的資料,請先指定其中一種排序方法,以便 決定結果的排序方式:

方法 用量
OrderByChild() 按照指定子鍵的值排序結果。
OrderByKey() 按子項鍵排序結果。
OrderByValue() 按照子項值排序結果。

一次只能使用「一個」排序方法。依訂單呼叫方法 重複計算錯誤。

以下範例說明如何訂閱分數 。

  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.

這會定義 firebase::Query,與 ValueListener 會將用戶端與排行榜同步處理 並按每個項目的分數排序。 如要進一步瞭解如何有效率地建立資料結構,請參閱 建立資料庫

OrderByChild() 方法的呼叫會指定要排序的子項鍵 產生結果在此情況下,結果會按照 "score" 的值排序。 每個子項的值如要進一步瞭解其他資料類型的排序方式, 請參閱查詢資料的排序方式

篩選資料

如要篩選資料,可以使用任何限製或範圍方法, 依順序排序查詢。

方法 用量
LimitToFirst() 設定從 結果的排序清單。
LimitToLast() 設定從訂單結尾傳回的項目數量上限 結果清單。
StartAt() 傳回大於或等於指定鍵或值的項目 視所選的訂單而定
EndAt() 傳回小於或等於指定鍵或值的項目 視所選的訂單而定
EqualTo() 傳回與指定鍵或值相等的項目 視所選的訂單而定

有別於逐一排序的方法,您可以合併多個限製或範圍函式。 例如,您可以結合 StartAt()EndAt() 方法 將結果傳回指定範圍內的值

即使查詢只有一個符合項目,快照仍會 清單;只會包含單一項目

限制結果數量

您可以使用 LimitToFirst()LimitToLast() 方法設定 要為特定回呼同步處理的子項數量上限。舉例來說 您使用 LimitToFirst() 將限制設為 100,一開始只會接收 至 100 個 OnChildAdded 回呼。如果您儲存的項目少於 100 個 Firebase 資料庫,每個項目都會觸發 OnChildAdded 回呼。

當項目變更時,系統會針對輸入值的項目接收 OnChildAdded 回呼 以及 OnChildRemoved 回呼, 總數會維持在 100

例如,以下程式碼會傳回排行榜的最高分:

  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.

依鍵或值篩選

您可以使用 StartAt()EndAt()EqualTo() 來選擇任意值 查詢的起點、結尾和對等點很適合用來 分頁資料或尋找具有特定值子項的項目。

查詢資料的排序方式

本節會說明 Query 類別。

OrderByChild

使用 OrderByChild() 時,包含指定子項鍵的資料將會是 排序如下:

  1. 針對指定子項鍵有 null 值的子項,如下所示 首先。
  2. 指定子鍵值為 false 的子項 取得下一個提示如果多個子項的值為 false,這些子項就會 依鍵字母順序排序。
  3. 指定子鍵值為 true 的子項 取得下一個提示如果多個子項的值為 true,這些子項就會 依索引鍵字母順序排列
  4. 含有數值的子項接著會以遞增順序排序。如果 多個子項的數值相同 節點,按鍵排序。
  5. 字串是由數字後方,並依字母順序遞增 順序。如果多個子項具有相同的值 節點的節點,按照鍵的字母順序排列。
  6. 物件在最後,且依索引鍵順序排列,以遞增順序排列。

OrderByKey

使用 OrderByKey() 排序資料時,系統會以遞增順序傳回資料 。

  1. 如果子項的索引鍵可剖析為 32 位元整數,其內容會先以遞增順序排序。
  2. 具有字串值做為索引鍵的下一個子項,並依字母順序遞增排序。

OrderByValue

使用 OrderByValue() 時,子項會按照值的順序排列。順序 條件與 OrderByChild() 相同,但節點值 ,而不是指定子鍵的值。

後續步驟