ios - Firebase:启用持久性后如何使用 observeSingleEvent OfType 获取最新的服务器数据?

标签 ios swift firebase firebase-realtime-database

我非常喜欢使用 Firebase 编写代码。它是具有各种不同工具集的出色后端。但是我错过了一种在启用持久性时检查更新数据路径的简单方法。我认为这不是一个罕见的用例,因为我经常需要我的应用程序根据最新的服务器数据以某种方式运行,只需要读取一次。

我通常会使用 observeSingleEventOfType,但是当启用持久性时它就没用了,因为它 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 中的所有消息,这是根本不需要的。

那么对于这两种情况是否有巧妙的解决方法呢?感谢您的帮助。

最佳答案

好的,我想我找到了适用于这两种情况的合理解决方法:

第一种情况的解决方法:

使用交易。它们只会在您在线时工作。 completion block 将返回最新的服务器数据。

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时跳过本地缓存的功能是必不可少的。

关于ios - Firebase:启用持久性后如何使用 observeSingleEvent OfType 获取最新的服务器数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38033720/

相关文章:

android - Facebook 身份验证不适用于 Android 中的 Firebase UI

ios - iOS Enterprise Program 是否允许向配置文件添加授权?

ios - 使用电子表格 Google Sheets API 创建新工作表

objective-c - 在 [AnyObject] Swift 中删除重复项的有效方法

ios - 只有第一个 collectionViewCell 对用户交互使用react

java - 向大约 15 个 Firebase 对象添加值/子事件是否会导致堆大小增加?

android - Android、iPhone、BlackBerry常用加解密算法

ios - 如何以 .amr 格式在 objective c 中为 iphone 应用程序录制音频?

ios - iOS (Swift 4) 中的 Azure AD B2C ROPC 流错误 - 资源所有者流只能由通过 B2C 管理门户创建的应用程序使用

java - Firebase 身份验证服务器错误