如何从 Firebase 快照解析单个字典?
How to Parse a Single Dictionary from Firebase Snapshot?
我的代码是:
_ = DataService.ds.REF_POSTS.child(key!).observe(.value, with: { (snapshot) in
})
key
等于 post 密钥 (-Kef2J6vJBCjHGYjSlkI)。我只想一次检索一个元素。
child下只有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")
}
}
}
})
'snap' 打印字典本身的元素,而不是整个字典。所以它总是在下一行转换失败。
忍者奖励:
如果您能提出更好的架构,我将不胜感激。
从 FB 中一个一个地检索 posts 似乎会大大降低性能。
之所以是'one by one',是因为这个post是用户GeoFire规范的结果。附近 post 的 Geofire returns 键。
我想根据返回的键过滤 Firebase 的 posts 主分支,但没有办法做到这一点 - 只能一个接一个地加载(.orderByChild - 不会 returns posts,而是订购所有 posts。如果您知道它如何帮助我,请提供建议)
这是您问题中提供的代码:
_ = 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
方法 returns 您在 FIRDataSnapshot
中提供的引用,其中 snapshot.key
是 child 的名称, snapshot.value
是包含的字典它 children.
因此,DataService.ds.REF_POSTS.child(key!).observe(.value, with: { (snapshot) in ... })
中的 snapshot
应该如下所示:
$post-id
imageUrl: http://...
likes: 0
userKey: ...
但是在下一行中,您使用本地定义重新定义了 snapshot
。这就是为什么你得到 post 的 children 的原因,因为你明确地这样定义它:
if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] { ... }
如果删除它,您应该会看到所需的行为。
那么你真正应该做什么?好吧,我不喜欢使用 .value
,因为它有一些缺点:
它下载请求的整个节点。如果您弄乱了对大节点的引用(即 ref/users),.value
操作很容易需要几秒钟才能看到 any 数据。
只调用一次。如果你的数据库是静态的,这很好,但是谁的数据库是静态的?
这就是为什么我更喜欢将 .childAdded
用于 post、消息等。它一次 returns 一个节点,这意味着您可以填充一个列表随着新数据的可用而逐步进行。使用一些聪明的 UI 函数(例如 tableView.insertRows(...)
你可以相当顺利地显示大量数据而无需等待结果。我相信它也支持分页,你可以在其中以 10 个为一组获取它们,例如. Here 是关于如何开始使用 .childAdded
充分利用大型数据列表的快速入门。
我的代码是:
_ = DataService.ds.REF_POSTS.child(key!).observe(.value, with: { (snapshot) in
})
key
等于 post 密钥 (-Kef2J6vJBCjHGYjSlkI)。我只想一次检索一个元素。
child下只有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")
}
}
}
})
'snap' 打印字典本身的元素,而不是整个字典。所以它总是在下一行转换失败。
忍者奖励:
如果您能提出更好的架构,我将不胜感激。
从 FB 中一个一个地检索 posts 似乎会大大降低性能。
之所以是'one by one',是因为这个post是用户GeoFire规范的结果。附近 post 的 Geofire returns 键。
我想根据返回的键过滤 Firebase 的 posts 主分支,但没有办法做到这一点 - 只能一个接一个地加载(.orderByChild - 不会 returns posts,而是订购所有 posts。如果您知道它如何帮助我,请提供建议)
这是您问题中提供的代码:
_ = 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
方法 returns 您在 FIRDataSnapshot
中提供的引用,其中 snapshot.key
是 child 的名称, snapshot.value
是包含的字典它 children.
因此,DataService.ds.REF_POSTS.child(key!).observe(.value, with: { (snapshot) in ... })
中的 snapshot
应该如下所示:
$post-id
imageUrl: http://...
likes: 0
userKey: ...
但是在下一行中,您使用本地定义重新定义了 snapshot
。这就是为什么你得到 post 的 children 的原因,因为你明确地这样定义它:
if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] { ... }
如果删除它,您应该会看到所需的行为。
那么你真正应该做什么?好吧,我不喜欢使用 .value
,因为它有一些缺点:
它下载请求的整个节点。如果您弄乱了对大节点的引用(即 ref/users),
.value
操作很容易需要几秒钟才能看到 any 数据。只调用一次。如果你的数据库是静态的,这很好,但是谁的数据库是静态的?
这就是为什么我更喜欢将 .childAdded
用于 post、消息等。它一次 returns 一个节点,这意味着您可以填充一个列表随着新数据的可用而逐步进行。使用一些聪明的 UI 函数(例如 tableView.insertRows(...)
你可以相当顺利地显示大量数据而无需等待结果。我相信它也支持分页,你可以在其中以 10 个为一组获取它们,例如. Here 是关于如何开始使用 .childAdded
充分利用大型数据列表的快速入门。