檢索數據

本文檔介紹了檢索資料以及如何排序和過濾 Firebase 資料的基礎知識。

在你開始之前

在使用即時資料庫之前,您需要:

  • 註冊您的 Unity 專案並將其配置為使用 Firebase。

    • 如果您的 Unity 專案已使用 Firebase,則它已針對 Firebase 進行註冊和設定。

    • 如果您沒有 Unity 項目,可以下載範例應用程式

  • Firebase Unity SDK (具體來說, FirebaseDatabase.unitypackage )新增到您的 Unity 專案中。

請注意,將 Firebase 新增至 Unity 專案涉及Firebase 控制台和開啟的 Unity 專案中的任務(例如,從控制台下載 Firebase 設定文件,然後將它們移至 Unity 專案中)。

檢索資料

Firebase 資料透過一次呼叫 GetValueAsync() 或附加到FirebaseDatabase參考上的事件來檢索。事件偵聽器在資料初始狀態時被呼叫一次,並在資料發生變化時再次呼叫。

取得資料庫參考

要從資料庫讀取數據,您需要一個DatabaseReference實例:

using Firebase;
using Firebase.Database;
using Firebase.Extensions.TaskExtension; // for ContinueWithOnMainThread

public class MyScript: MonoBehaviour {
  void Start() {
    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

讀取一次數據

您可以使用GetValueAsync方法讀取給定路徑中內容的靜態快照一次。任務結果將包含一個快照,其中包含該位置的所有數據,包括子數據。如果沒有數據,則傳回的快照為null

    FirebaseDatabase.DefaultInstance
      .GetReference("Leaders")
      .GetValueAsync().ContinueWithOnMainThread(task => {
        if (task.IsFaulted) {
          // Handle the error...
        }
        else if (task.IsCompleted) {
          DataSnapshot snapshot = task.Result;
          // Do something with snapshot...
        }
      });

監聽事件

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

事件典型用法
ValueChanged讀取並監聽路徑整個內容的變更。
ChildAdded檢索項目清單或偵聽項目清單的新增內容。建議與ChildChangedChildRemoved一起使用來監視清單的變更。
ChildChanged監聽清單中項目的變更。與ChildAddedChildRemoved一起使用來監視清單的變更。
ChildRemoved偵聽從清單中刪除的項目。與ChildAddedChildChanged一起使用來監視清單的變更。
ChildMoved偵聽有序清單中項目順序的變更。 ChildMoved事件總是跟隨導致專案順序變更的ChildChanged事件(基於目前的排序方式)。

值更改事件

您可以使用ValueChanged事件來訂閱給定路徑中內容的變更。此事件在附加偵聽器時觸發一次,每次資料(包括子項目)發生變更時都會觸發一次。向事件回調傳遞包含該位置的所有資料(包括子資料)的快照。如果沒有數據,則傳回的快照為null

以下範例示範了一個從資料庫中檢索排行榜分數的遊戲:

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

ValueChangedEventArgs包含一個DataSnapshot ,其中包含事件發生時資料庫中指定位置的資料。在快照上呼叫Value將傳回表示資料的Dictionary<string, object> 。如果該位置不存在數據,則呼叫Value將傳回null

在此範例中,也會檢查args.DatabaseError以查看讀取是否已取消。例如,如果用戶端無權從 Firebase 資料庫位置讀取,則可以取消讀取。 DatabaseError將指示發生故障的原因。

您稍後可以使用具有相同路徑的任何DatabaseReference取消訂閱該事件。 DatabaseReference實例是短暫的,可以被視為存取任何路徑和查詢的一種方式。

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged -= HandleValueChanged; // unsubscribe from ValueChanged.
    }

兒童活動

子事件是為了回應節點子節點發生的特定操作而觸發的,這些操作例如透過Push()方法新增的新子節點或透過UpdateChildrenAsync()方法更新的子節點。這些中的每一個都可以用於偵聽資料庫中特定節點的變更。例如,遊戲可能會同時使用這些方法來監視遊戲會話評論中的活動,如下所示:

      var ref = FirebaseDatabase.DefaultInstance
      .GetReference("GameSessionComments");

      ref.ChildAdded += HandleChildAdded;
      ref.ChildChanged += HandleChildChanged;
      ref.ChildRemoved += HandleChildRemoved;
      ref.ChildMoved += HandleChildMoved;
    }

    void HandleChildAdded(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildChanged(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildRemoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildMoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

ChildAdded事件通常用於擷取 Firebase 資料庫中的項目清單。對於每個現有子項, ChildAdded事件都會引發一次,然後每次將新子項新增至指定路徑時都會引發一次。偵聽器會收到包含新子項目資料的快照。

每當修改子節點時都會引發ChildChanged事件。這包括對子節點的後代的任何修改。它通常與ChildAddedChildRemoved事件結合使用,以回應項目清單的變更。傳遞給事件偵聽器的快照包含子層級的更新資料。

當直接子項被刪除時,將觸發ChildRemoved事件。它通常與ChildAddedChildChanged回調結合使用。傳遞給事件回呼的快照包含已刪除子項目的資料。

每當因導致子級重新排序的更新而引發ChildMoved事件時,都會觸發ChildChanged事件。它與透過OrderByChildOrderByValue排序的資料一起使用。

排序和過濾數據

您可以使用即時資料庫Query類別來擷取按鍵、按值或按子值排序的資料。您也可以將排序結果過濾為特定數量的結果或一系列鍵或值。

對資料進行排序

若要擷取排序的數據,請先指定排序方法之一來確定結果的排序方式:

方法用法
OrderByChild()依指定子鍵的值對結果進行排序。
OrderByKey()按子鍵對結果進行排序。
OrderByValue()依子值對結果進行排序。

您一次只能使用一種排序方式。在同一查詢中多次呼叫 order-by 方法會引發錯誤。

以下範例示範如何訂閱按分數排序的分數排行榜。

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

這定義了一個查詢,當與valuechanged 事件偵聽器結合使用時,會將用戶端與資料庫中的排行榜同步,並按每個條目的分數排序。您可以在建立資料庫中閱讀有關有效建立資料的更多資訊。

OrderByChild()方法的呼叫指定用於對結果進行排序的子鍵。在這種情況下,結果會依照每個子項中的"score"值排序。有關其他資料類型如何排序的詳細信息,請參閱查詢資料如何排序

過濾數據

要過濾數據,您可以在建構查詢時將任何限製或範圍方法與排序方法結合。

方法用法
LimitToFirst()設定從有序結果清單開頭傳回的最大項目數。
LimitToLast()設定從有序結果清單末尾傳回的最大項目數。
StartAt()根據所選的排序方法,傳回大於或等於指定鍵或值的項目。
EndAt()根據所選的排序方法,傳回小於或等於指定鍵或值的項目。
EqualTo()根據所選的排序方法,傳回等於指定鍵或值的項目。

與排序方法不同,您可以組合多個限製或範圍函數。例如,您可以組合StartAt()EndAt()方法將結果限制為指定的值範圍。

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

限制結果數量

您可以使用LimitToFirst()LimitToLast()方法來設定給定回呼要同步的子級的最大數量。例如,如果您使用LimitToFirst()將限制設為 100,則最初最多只會收到 100 個ChildAdded回呼。如果您的 Firebase 資料庫中儲存的項目少於 100 個,則每個項目都會觸​​發ChildAdded回呼。

當項目發生變更時,您會收到進入查詢的項目的ChildAdded回調和退出查詢的項目的ChildRemoved回調,以便總數保持在 100。

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

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score").LimitToLast(1)
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

按鍵或值過濾

您可以使用StartAt()EndAt()EqualTo()為查詢選擇任意起始點、結束點和等價點。這對於對資料進行分頁或尋找具有特定值的子項目非常有用。

查詢資料如何排序

本節說明如何透過Query類別中的每個 order-by 方法對資料進行排序。

OrderByChild

使用OrderByChild()時,包含指定子鍵的資料會依下列方式排序:

  1. 指定子鍵的值為null子項排在第一位。
  2. 接下來是指定子鍵值為false的子項。如果多個子項的值為false ,則它們按鍵按字典順序排序。
  3. 接下來是指定子鍵值為true的子項。如果多個子項的值為true ,則它們按鍵按字典順序排序。
  4. 接下來是具有數值的子項,依升序排序。如果指定子節點的多個子節點具有相同的數值,則它們會按鍵排序。
  5. 字串位於數字之後,並依字典順序升序排序。如果指定子節點的多個子節點具有相同的值,則它們按鍵按字典順序排序。
  6. 物件排在最後,並依字典順序按鍵升序排序。

OrderByKey

當使用OrderByKey()對資料進行排序時,資料將按鍵升序傳回。

  1. 具有可解析為 32 位元整數的鍵的子項排在前面,按升序排序。
  2. 接下來是以字串值作為鍵的子項,依字典順序升序排列。

OrderByValue

使用OrderByValue()時,子項會依其值排序。排序標準與OrderByChild()中的相同,只是使用節點的值而不是指定子鍵的值。