假设我的Firebase数据中有一系列键,表示与另一部分数据的关系。这是一个例子:
{
"messages": {
"m1": {
"text": "123"
},
"m2": {
"text": "123"
},
"m3": {
"text": "123"
}
},
"rooms": {
"r1": {
"messages": {
"1": "m1",
"2": "m2",
"3": "m3"
}
}
}
}
我们有3封邮件,每封邮件都有一个ID,还有一个房间,其中包含属于该房间的Firebase数组的邮件ID。这是Firebase上非常常见的模式。
因此,在代码中,我获得了一系列消息ID,我将其迭代以创建Firebase Refs。
let messageIDs = snapshot.value["messages"] as! [String]
var refs: [Firebase] = []
for mID in messageIDs {
refs.append(Firebase("https://firebase.com/messages/" + mID))
}
一切都好。这可以按预期工作。
现在我想在列表中显示所有这些消息。有没有办法一次加载所有这些项目?我可以循环遍历这些Refs并对每一个进行一次观察,但是当我们回来时我需要管理结果。或许这是唯一的方法吗?有没有人以前处理过这个问题?
答案 0 :(得分:2)
问题和现有结构可能还有更多,但这种结构可能会简化事情吗?
messages:
message_id_0:
msg_num: 1
text: "123"
room: r1
message_id_1:
msg_num: 1
text: "123"
room: r3
message_id_2:
msg_num: 2
text: "123"
room: r1
然后获取房间r1的所有消息
ref.queryOrderedByChild("room").queryEqualToValue("r1")
.observeEventType(.Value, withBlock: { snapshot in
println(snapshot.value)
})
将返回房间r1的单个快照中的所有消息,其中包含msg_num(用于排序)和每条消息的文本。
该结构打破了节点名称与其包含的数据之间的链接,这将增加更多的灵活性。哦,它消除了对阵列的需要;在可能的情况下避免使用Firebase中的数组可能是个好主意。
答案 1 :(得分:1)
如果消息恰好出现在序列中,您可以执行range query来获取所有消息。来自文档:
let ref = Firebase(url:"https://dinosaur-facts.firebaseio.com/dinosaurs")
ref.queryOrderedByKey().queryStartingAtValue("b").queryEndingAtValue("b\u{f8ff}")
.observeEventType(.ChildAdded, withBlock: { snapshot in
println(snapshot.key)
})
但很可能这些消息不会(始终)是连续的。在这种情况下,您确实必须循环遍历它们并依次使用observeSingleEventOfType
加载它们。这在代码中确实需要更多工作,因为您需要将结果合并到单个列表/数组中。
许多开发人员担心此操作的性能,但这并不像您最初想的那么糟糕。请求将全部通过Firebase保持打开的套接字进行流水线处理,因此序列很可能是:
发送请求1
发送请求2
发送请求3
...稍等一下服务器
得到答复1
得到答复2
得到答复3
请求的发送和响应的接收将在您等待一次延迟和数据库查找项目之间彼此接近。