本頁面由 Cloud Translation API 翻譯而成。
Switch to English

在iOS上使用數據列表

獲取FIRDatabaseReference

要從數據庫讀取或寫入數據,您需要一個FIRDatabaseReference實例:

迅速

var ref: DatabaseReference!

ref = Database.database().reference()

物鏡

@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

讀寫清單

附加到數據列表

使用childByAutoId方法可將數據追加到多用戶應用程序中的列表中。每當將新的子項添加到指定的Firebase引用中時, childByAutoId方法都會生成一個唯一鍵。通過對列表中的每個新元素使用這些自動生成的鍵,多個客戶端可以將子代同時添加到同一位置,而不會發生寫衝突。 childByAutoId生成的唯一鍵是基於時間戳的,因此列表項childByAutoId時間順序自動排序。

您可以使用對childByAutoId方法返回的新數據的引用來獲取子項的自動生成鍵的值或為子項設置數據。在childByAutoId引用上調用getKey返回自動生成的密鑰。

您可以使用這些自動生成的鍵來簡化扁平化數據結構。有關更多信息,請參見數據扇出示例

聽兒童活動

子事件是響應於某個操作(例如通過childByAutoId方法添加的新子childByAutoId或通過updateChildValues方法更新的子項)對節點子項發生的特定操作而觸發的。

事件類型典型用法
FIRDataEventTypeChildAdded 檢索項目列表或收聽對項目列表的添加。為每個現有子項觸發一次此事件,然後每次將新子項添加到指定路徑時再次觸發。向偵聽器傳遞一個包含新子數據的快照。
FIRDataEventTypeChildChanged 偵聽列表中項目的更改。修改子節點時,都會觸發此事件。這包括對子節點後代的任何修改。傳遞給事件偵聽器的快照包含子項的更新數據。
FIRDataEventTypeChildRemoved 偵聽從列表中刪除的項目。刪除直接子項時觸發此事件。傳遞給回調塊的快照包含已刪除子項的數據。
FIRDataEventTypeChildMoved 偵聽有序列表中項目順序的更改。每當更新導致子級重新排序時,都會觸發此事件。它與由queryOrderedByChildqueryOrderedByValue排序的數據queryOrderedByValue

這些中的每一個都可以用於偵聽數據庫中特定節點的更改。例如,社交博客應用程序可能一起使用這些方法來監視帖子評論中的活動,如下所示:

迅速

// Listen for new comments in the Firebase database
commentsRef.observe(.childAdded, with: { (snapshot) -> Void in
  self.comments.append(snapshot)
  self.tableView.insertRows(at: [IndexPath(row: self.comments.count-1, section: self.kSectionComments)], with: UITableView.RowAnimation.automatic)
})
// Listen for deleted comments in the Firebase database
commentsRef.observe(.childRemoved, with: { (snapshot) -> Void in
  let index = self.indexOfMessage(snapshot)
  self.comments.remove(at: index)
  self.tableView.deleteRows(at: [IndexPath(row: index, section: self.kSectionComments)], with: UITableView.RowAnimation.automatic)
})

物鏡

// Listen for new comments in the Firebase database
[_commentsRef
              observeEventType:FIRDataEventTypeChildAdded
              withBlock:^(FIRDataSnapshot *snapshot) {
                [self.comments addObject:snapshot];
                [self.tableView insertRowsAtIndexPaths:@[
                  [NSIndexPath indexPathForRow:self.comments.count - 1 inSection:kSectionComments]
                ]
                                      withRowAnimation:UITableViewRowAnimationAutomatic];
              }];
// Listen for deleted comments in the Firebase database
[_commentsRef
 observeEventType:FIRDataEventTypeChildRemoved
 withBlock:^(FIRDataSnapshot *snapshot) {
   int index = [self indexOfMessage:snapshot];
   [self.comments removeObjectAtIndex:index];
   [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:kSectionComments]]
                         withRowAnimation:UITableViewRowAnimationAutomatic];
 }];

聆聽價值事件

雖然偵聽子事件是讀取數據列表的推薦方法,但在某些情況下,偵聽列表引用中的值事件很有用。

FIRDataEventTypeValue觀察器附加到數據列表將以單個DataSnapshot的形式返回整個數據列表,然後可以循環訪問單個子級。

即使查詢只有一個匹配項,快照仍是一個列表。它只包含一個項目。要訪問該項目,您需要遍歷結果:

迅速

_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

物鏡

[_commentsRef
              observeEventType:FIRDataEventTypeValue
              withBlock:^(FIRDataSnapshot *snapshot) {
                // Loop over children
                NSEnumerator *children = [snapshot children];
                FIRDataSnapshot *child;
                while (child = [children nextObject]) {
                  // ...
                }
              }];

當您希望通過單個操作獲取列表的所有子項,而不是偵聽其他已添加子項的事件時,此模式很有用。

排序和過濾數據

您可以使用Realtime Database FIRDatabaseQuery類檢索按鍵,按值或按子項值排序的數據。您還可以將排序的結果篩選為特定數目的結果或一定範圍的鍵或值。

排序數據

要檢索排序的數據,請先指定一種排序方法來確定結果的排序方式:

方法用法
queryOrderedByKey 通過子鍵訂購結果。
queryOrderedByValue 按子值排序結果。
queryOrderedByChild 按指定的子鍵或嵌套子路徑的值對結果進行排序。

您一次只能使用一種訂購方式。在同一查詢中多次調用order-by方法會引發錯誤。

下面的示例演示如何檢索按用戶星數排序的用戶熱門帖子列表:

迅速

// My top posts by number of stars
let myTopPostsQuery = (ref.child("user-posts").child(getUid())).queryOrdered(byChild: "starCount")

物鏡

// My top posts by number of stars
FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"]
                                      child:[super getUid]]
                                     queryOrderedByChild:@"starCount"];

該查詢根據用戶ID從數據庫路徑中檢索用戶的帖子,並按每個帖子已接收的星數排序。這種將ID用作索引鍵的技術稱為數據扇出,您可以在“ 數據庫結構”中閱讀有關它的更多信息。

調用queryOrderedByChild方法指定用於對結果進行排序的子項。在此示例中,帖子按每個帖子中"starCount"子代的值排序。如果您的數據看起來像這樣,查詢也可以由嵌套子級進行排序:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

在這種情況下,我們可以通過在queryOrderedByChild調用中指定嵌套子項的相對路徑,通過嵌套在metrics鍵下的值對列表元素進行queryOrderedByChild

迅速

 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

目標C

 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

有關如何排序其他數據類型的更多信息,請參見查詢數據的排序方式

篩選資料

要過濾數據,可以在構造查詢時將任何limit方法或range方法與order-by方法結合使用。

方法用法
queryLimitedToFirst 設置從有序結果列表的開頭返回的最大項目數。
queryLimitedToLast 設置要從已排序結果列表的末尾返回的最大項目數。
queryStartingAtValue 根據選擇的排序方式,返回大於或等於指定鍵或值的項目。
queryEndingAtValue 根據選擇的排序方式,返回小於或等於指定鍵或值的項目。
queryEqualToValue 根據選擇的排序方法,返回等於指定鍵或值的項目。

與order-by方法不同,您可以組合多個限製或範圍函數。例如,可以組合使用queryStartingAtValuequeryEndingAtValue方法將結果限制為指定的值範圍。

限制結果數

您可以使用queryLimitedToFirstqueryLimitedToLast方法設置給定回調要同步的最大子級數。例如,如果使用queryLimitedToFirst設置限制為100,則最初最多只能接收100個FIRDataEventTypeChildAdded回調。如果您在Firebase數據庫中存儲的項目少於100個, FIRDataEventTypeChildAdded為每個項目觸發FIRDataEventTypeChildAdded回調。

隨著項目的變化,您會收到FIRDataEventTypeChildAdded回調對於輸入查詢和項目FIRDataEventTypeChildRemoved回調,在100它的輟學,使總數停留項目。

以下示例演示了示例博客應用程序如何檢索所有用戶的100條最新帖子的列表:

迅速

// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!

目標C

// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

按鍵或值過濾

您可以使用queryStartingAtValuequeryEndingAtValuequeryEqualToValue為查詢選擇任意的起點,終點和等價點。這對於分頁數據或查找具有特定值的子項的項目可能很有用。

查詢數據如何排序

本節說明如何通過FIRDatabaseQuery類中的每個order-by方法對數據進行排序。

queryOrderedByKey

使用queryOrderedByKey對數據進行排序時,數據會按鍵升序返回。

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

queryOrderedByValue

使用queryOrderedByValue ,子項按其值排序。排序條件與queryOrderedByChild的排序條件相同,除了使用節點的值代替指定的子鍵的值之外。

queryOrderedByChild

使用queryOrderedByChild ,包含指定子鍵的數據按以下順序排序:

  1. 指定子項的值為nil的子項優先。
  2. 接下來是指定子項的值為false的子項。如果多個子項的值為false則按字母順序對它們進行排序。
  3. 接下來是指定子項的值為true的子項。如果多個子項的值為true ,則按字母順序對它們進行排序。
  4. 接下來是帶有數字值的子級,以升序排列。如果多個子節點的指定子節點具有相同的數值,則按鍵對它們進行排序。
  5. 字符串緊隨數字之後,並按字典順序升序排序。如果多個子節點在指定的子節點上具有相同的值,則按字母順序對它們進行排序。
  6. 對象排在最後,並按字母順序從小到大按字母順序排序。

分離聽眾

當您離開ViewController時,觀察者不會自動停止同步數據。如果未正確刪除觀察者,它將繼續將數據同步到本地內存。當不再需要觀察者時,可以通過將關聯的FIRDatabaseHandle傳遞給removeObserverWithHandle方法來移除它。

當您將回調塊添加到引用時,將返回FIRDatabaseHandle 。這些句柄可用於刪除回調塊。

如果已將多個偵聽器添加到數據庫引用,則在引發事件時將調用每個偵聽器。為了停止在該位置同步數據,必須通過調用removeAllObservers方法刪除該位置的所有觀察者。

在偵聽器上調用removeObserverWithHandleremoveAllObservers不會自動刪除在其子節點上註冊的偵聽器。您還必須跟踪這些引用或句柄以將其刪除。

下一步