2017-03-29 26 views
0

我的代碼是:如何解析Firebase快照中的單個字典?

_ = DataService.ds.REF_POSTS.child(key!).observe(.value, with: { (snapshot) in 

       }) 

key等於交鍵(-Kef2J6vJBCjHGYjSlkI)。我想一次只檢索一個元素。
只有1這個孩子在字典:

enter image description here

我需要創建一個字典出了這樣的內容。但是,當我執行常規算法時:'快照'打印字典本身的元素,而不是整個字典。所以它總是在下面一行中轉換失敗。


紅利忍者:

如果你能提出一個更好的架構,我對此表示讚賞。 看來,逐個從FB中檢索帖子會顯着降低性能。
它是'一個一個'的原因是這篇文章是用戶的GeoFire規範的結果。 Geofire將密鑰返回到附近的帖子。 我想根據那些返回的密鑰過濾Firebase的帖子主分支,但是沒有辦法做到這一點 - 只能逐個加載(.orderByChild - 不會返回帖子,而是指定所有帖子。你知道如何能幫助我,請諮詢)

回答

1

這是你的問題提供的代碼:

_ = DataService.ds.REF_POSTS.child(key!).observe(.value, with: { (snapshot) in 

if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] { 
     for snap in snapshot { 
      print("Zhenya: here is the snap: \(snap)") 
      if let postDict = snap.value as? Dictionary<String, AnyObject> { 
       let key = snap.key 
       let post = Post(postKey: key, postData: postDict) 
       self.posts.append(post) 
      } else { 
       print("Zhenya: failed to convert") 
      } 
     } 
    } 
}) 

讓我們來看看這裏發生了什麼。

第一行使用.value方法在Firebase中觀察posts/$post-id.value方法返回您在FIRDataSnapshot中提供的參考,其中snapshot.key是兒童的名稱,snapshot.value是包含其子女的字典。

所以,snapshotDataService.ds.REF_POSTS.child(key!).observe(.value, with: { (snapshot) in ... })應該是這樣的:

$post-id 
    imageUrl: http://... 
    likes: 0 
    userKey: ... 

但在非常下一行你使用的是本地的定義重新界定snapshot。這就是爲什麼你獲得這個職位的孩子,因爲你明確地定義這樣的說法:

if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] { ... } 

如果您刪除此,你會看到你想要的行爲。


那麼你應該怎麼做?好吧,我不喜歡使用.value,因爲它有一些缺點:

  • 它下載請求的整個節點。如果你搞砸你的大型節點的參考(我。e,ref/users),在您看到任何數據之前,.value操作很容易花費幾秒鐘。

  • 它只被調用一次。這很好,如果你的數據庫是靜態的,但是其數據庫是靜態的?

這就是爲什麼我更喜歡使用.childAdded喜歡的事情的帖子,消息等它返回在時間的單個節點,這意味着新的數據可用時,你可以逐步填充列表。使用一些聰明的UI功能(例如tableView.insertRows(...)),您可以在不等待結果的情況下平穩地顯示大量數據列表,我相信它也支持分頁,例如,您可以批量分配10個分頁。您可以開始使用.childAdded來充分利用大量數據列表

+0

FB文檔說,.value總是返回一個FIRDataSnapshot數組,即使只有一個元素,如果我刪除該行並直接轉換'snapshot'到'Dictionary ',我得到了'從'FIRDataSnapshot'轉換爲不相關的類型'Dictionary '總是失敗''因此,我的條件從來就不是真的 – Evgeny

+2

它的工作,我沒有刪除'.value'參數你是對的,正確的方法應該是'如果讓postDict = snapshot.value爲?Dictionary {...}' 謝謝森林! – Evgeny

+1

@Evgeny我更新了我的答案,並說明了「快照」的真實含義。 –