我非常喜欢使用Firebase进行编码。它是一个很棒的后端,有各种不同的工具集。但是,当启用持久性时,我想念一种检查更新数据路径的简单方法。我认为这不是一个很少使用的例子,因为我经常需要我的应用程序以某种方式操作,具体取决于最新的服务器数据,只需要读取一次。
我通常会使用observeSingleEventOfType
,但是当启用perisistance时它会毫无用处,因为它will never retrieve the latest server data。我不明白为什么。应该添加一个选项以跳过本地缓存并仅查找服务器数据。
禁用持久性可解决此问题,observeSingleEventOfType
将按预期工作。但这意味着需要自己重新实现所有离线功能。
第一种情况:
// chats contain meta information about the chat like last message and count of unread messages
let chatRef = ref.child("chats").child(receiverId).child(chatId)
chatRef.observeSingleEventOfType(.Value, withBlock: { (snapshot) -> Void in
if !snapshot.exists() {
print("snapshot does not exist")
// the other side has deleted the chat
// now delete all messages and member objects
ref.child("messages").child(chatId).setValue(nil)
ref.child("members").child(chatId).setValue(nil)
} else {
print("snapshot exists")
}
})
在观察没有运气的事件之前,我也试过了chatRef.keepSynced(true)
。无论如何,这在所有情况下都没有意义:
第二种情况:
func removeOlderMessages() {
let dateInThePast = NSDate().addDays(-30).timeIntervalSince1970 * 1000
self.messagesRef.queryOrderedByChild("timestamp")
.queryEndingAtValue(dateInThePast)
.observeSingleEventOfType(.Value, withBlock: { (snapshot) -> Void in
snapshot.ref.removeValue()
})
}
在此处使用keepSynced
将导致下载messagesRef
中的所有邮件,这根本不需要。
这两种情况有一个聪明的解决方法吗?任何帮助表示赞赏。
答案 0 :(得分:3)
好的,我认为我找到了两种方案的合理解决方法:
第一种方案的解决方法:
使用transactions
。它们只能在您上线时使用。 completition
块将返回最新的服务器数据。
self.ref.child("chats").child(receiverId).child(chatId).runTransactionBlock({ (currentData) -> FIRTransactionResult in
// Actually do nothing with the retrieved data and re-submit it.
return FIRTransactionResult.successWithValue(currentData)
}) { (error, success, snapshot) in
if let error = error {
print(error)
return
} else if !success || snapshot == nil {
return
}
// snapshot contains the latest server data
if !snapshot!.exists() {
// the other side has deleted the chat
// now delete all messages and member objects
print("snapshot doesn't exist. deleting messages and members.")
ref.child("messages").child(chatId).setValue(nil)
ref.child("members").child(chatId).setValue(nil)
} else {
print("snapshot exists. not deleting all messages and members.")
}
}
缺点是与observeEventType
或observeSingleEventOfType
相比,检索数据需要相当长的时间。
第二种方案的解决方法:
使用observeEventType(.Value)
。它将首先返回缓存然后最新的服务器数据(如果可用)。在NSTimer
的设定时间间隔后,可以删除观察者。
所有这些变通办法现在都可以,但使用observeSingleEventOfType
时跳过本地缓存的功能是必不可少的。