Firebase:如何在启用持久性时使用observeSingleEventOfType获取最新的服务器数据?

时间:2016-06-25 23:07:59

标签: ios swift firebase firebase-realtime-database

我非常喜欢使用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中的所有邮件,这根本不需要。

这两种情况有一个聪明的解决方法吗?任何帮助表示赞赏。

1 个答案:

答案 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.")
    }     
}

缺点是与observeEventTypeobserveSingleEventOfType相比,检索数据需要相当长的时间。

第二种方案的解决方法:

使用observeEventType(.Value)。它将首先返回缓存然后最新的服务器数据(如果可用)。在NSTimer的设定时间间隔后,可以删除观察者。

所有这些变通办法现在都可以,但使用observeSingleEventOfType时跳过本地缓存的功能是必不可少的。