我的代码是:
_ = DataService.ds.REF_POSTS.child(key!).observe(.value, with: { (snapshot) in
})
key
等于后置密钥(-Kef2J6vJBCjHGYjSlkI)。我想一次只检索一个元素
那个孩子下面只有一本字典:
我需要从中创建一个字典。但是,当我实现常规算法时:
_ = 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")
}
}
}
})
'snap'打印字典本身的元素,而不是整个字典。所以它总是在下一行的转换失败。
忍者奖金:
如果您可以建议更好的架构,我将不胜感激。 似乎从FB逐个检索帖子会大大降低性能 它是“一个接一个”的原因是这个帖子是用户的GeoFire规范的结果。 Geofire会将密钥返回到附近的帖子。 我想根据返回的密钥过滤Firebase的主要帖子分支,但是没有办法做到这一点 - 只能逐个加载(.orderByChild - 不返回帖子,而是命令所有帖子。如果你是知道它可以帮助我,请建议)
答案 0 :(得分:2)
这是您问题中提供的代码:
_ = 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")
}
}
}
})
让我们来看看这里发生了什么。
第一行是使用posts/$post-id
方法在Firebase中观察.value
。 .value
方法会返回您在FIRDataSnapshot
中提供的引用,其中snapshot.key
是子名称,snapshot.value
是包含其子项的字典。
因此,snapshot
中的DataService.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
,因为它有一些缺点:
下载请求的整个节点。如果你搞砸了大型节点(即ref / users)的引用,那么.value
操作很容易在你看到任何数据之前需要几秒钟。
只调用一次。如果您的数据库是静态的,但其数据库是静态的,那么这很好吗?
这就是为什么我更喜欢将.childAdded
用于帖子,消息等等。它一次返回一个节点,这意味着您可以在新数据可用时逐步填充列表。使用一些聪明的UI功能(例如tableView.insertRows(...)
,您可以非常顺利地显示大型数据列表而无需等待结果。我相信它也支持分页,例如,您可以在10个批次中获取它们。{{3是一个快速入门,介绍如何开始使用.childAdded
来充分利用大型数据列表。