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

MJQ*_*347 10 ios firebase swift firebase-realtime-database

我非常喜欢使用Firebase进行编码.它是一个很棒的后端,有各种不同的工具集.但是,当启用持久性时,我想念一种检查更新数据路径的简单方法.我认为这不是一个很少的用例,因为我经常需要我的应用程序以某种方式操作,具体取决于最新的服务器数据,只需要读取一次.

我通常会使用observeSingleEventOfType,但是当启用perisistance时它没用,因为它永远不会检索最新的服务器数据.其中我不明白为什么.应该添加一个选项以跳过本地缓存并仅查找服务器数据.

禁用持久性可解决此问题,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")
     }
 })
Run Code Online (Sandbox Code Playgroud)

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()
    })
}
Run Code Online (Sandbox Code Playgroud)

keepSynced在这里使用将导致下载所有消息messagesRef,根本不需要.

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

MJQ*_*347 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.")
    }     
}
Run Code Online (Sandbox Code Playgroud)

缺点是与observeEventType或相比,检索数据所需的时间要长得多observeSingleEventOfType

第二种情况的解决方法:

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

总而言之,目前这些解决办法都可以,但是使用时跳过本地缓存的功能observeSingleEventOfType是必不可少的。