本文檔介紹了檢索數據以及如何排序和過濾 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 | 檢索項目列表或偵聽項目列表的添加內容。建議與ChildChanged 和ChildRemoved 一起使用來監視列表的更改。 |
ChildChanged | 監聽列表中項目的更改。與ChildAdded 和ChildRemoved 一起使用來監視列表的更改。 |
ChildRemoved | 偵聽從列表中刪除的項目。與ChildAdded 和ChildChanged 一起使用來監視列表的更改。 |
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
事件。這包括對子節點的後代的任何修改。它通常與ChildAdded
和ChildRemoved
事件結合使用,以響應項目列表的更改。傳遞給事件偵聽器的快照包含子級的更新數據。
當直接子項被刪除時,將觸發ChildRemoved
事件。它通常與ChildAdded
和ChildChanged
回調結合使用。傳遞給事件回調的快照包含已刪除子項的數據。
每當因導致子級重新排序的更新而引發ChildMoved
事件時,都會觸發ChildChanged
事件。它與通過OrderByChild
或OrderByValue
排序的數據一起使用。
排序和過濾數據
您可以使用實時數據庫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()
時,包含指定子鍵的數據按如下方式排序:
- 指定子鍵的值為
null
子項排在第一位。 - 接下來是指定子鍵值為
false
的子項。如果多個子項的值為false
,則它們按鍵按字典順序排序。 - 接下來是指定子鍵值為
true
的子項。如果多個子項的值為true
,則它們按鍵按字典順序排序。 - 接下來是具有數值的子項,按升序排序。如果指定子節點的多個子節點具有相同的數值,則它們按鍵排序。
- 字符串位於數字之後,並按字典順序升序排序。如果指定子節點的多個子節點具有相同的值,則它們按鍵按字典順序排序。
- 對象排在最後,並按字典順序按鍵升序排序。
OrderByKey
當使用OrderByKey()
對數據進行排序時,數據將按鍵升序返回。
- 具有可解析為 32 位整數的鍵的子項排在前面,按升序排序。
- 接下來是以字符串值作為鍵的子項,按字典順序升序排列。
OrderByValue
使用OrderByValue()
時,子項按其值排序。排序標準與OrderByChild()
中的相同,只是使用節點的值而不是指定子鍵的值。