ios - Firebase:下次应用程序启动时如何只检索更改的项目?

标签 ios firebase firebase-realtime-database

我有一个应用程序使用包含 100,000 个项目的 Firebase 数据库。我的应用程序必须处理这些项目中的每一项,这需要几秒钟的时间。 发生的情况是,每次启动应用程序(从终止状态)时,每次都会处理这 100,000 个项目(即使 Firebase 服务器上的数据库内容没有改变)。显然,如果没有必要,我不希望应用程序执行此操作。这是一些代码:

if dbRef == nil {
    FirebaseApp.configure();
    Database.database().isPersistenceEnabled = true
    ...
    let dbRef = Database.database().reference(withPath: kFirebaseDBName)
    _ = spamRef.observe(DataEventType.value, with: { (theSnapshot) in
        if let content = theSnapshot.value as? [String : AnyObject]
        {
            self.processContent(content: content)
        }

每次启动应用程序时,内容快照都会包含整个数据库引用内容。

有没有办法,例如,获取数据库更新的最后日期(在服务器上),或者只获取每次应用程序启动之间更改项目的增量 - 例如,查询可以返回自上次查询以来刚刚更改的内容吗,或类似的东西?

我不知道有多少项目发生了变化,所以不能这样调用: queryLimited(toLast:N)) 因为我不知道 N 的值是多少。

我试过如下添加 keepSynced,希望它能改变一些事情,但没有。

if dbRef == nil {
    FirebaseApp.configure();
    Database.database().isPersistenceEnabled = true
    ...
    let dbRef = Database.database().reference(withPath: kFirebaseDBName)
    dbRef.keepSynced(true) 
    _ = dbRef.observe(DataEventType.value, with: { (theSnapshot) in
        if let content = theSnapshot.value as? [String : AnyObject]
        {
            self.processContent(content: content)
        }

我不知道有多少数据可能发生了变化,所以不知道要为 toLast 或类似的东西提供什么值来修改观察参数。 数据库(不是我创建的,也不是我用新内容更新的)在平面结构中有 100,000 个项目(即一个 parent 有 100,000 个 child ),自从上次我的应用程序以来,这些 child 中的任何数量的任何顺序都可能已被删除和替换跑了,但总数仍然是 100,000。没有一个 child 有明确的时间戳或类似的东西。

我的印象是,如果 Firebase 保留数据的本地缓存(由于 isPersistenceEnabled),那么下次它连接到服务器时,它只会同步服务器上发生的更改。因此,为了做到这一点,Firebase 本身必须在内部某处有一些增量信息,所以我希望增量信息可以某种形式提供给我的应用程序。

注意:我的应用程序不需要启用持久性,上面的代码这样做只是为了查看是否有任何东西会导致我希望观察者的行为。

最佳答案

更新

所以看着 documentation更多您可以设置用户最后一次连接到服务器的时间戳:

lastOnlineRef.onDisconnectSetValue(ServerValue.timestamp())

看看this question弗兰克解释了一些与坚持和听众有关的问题。问题是针对 Android 的,但原理是相同的。

我仍然认为问题出在您的查询上。由于您已经保留了数据,.value 不是您想要的,因为这会返回所有数据。

我认为您想将 .childChanged 监听器附加到您的查询。在这种情况下,查询将只返回已更改的数据。如果您在阅读之前还没有听说过 .childChanged here .

我没有意识到这个问题与持久性特别相关。我认为您正在寻找 keepSynced()。看看this .

原始答案

问题出在您的查询上。您正在请求所有数据,这就是您获取所有数据的原因。您想使用 toFirst or toLast 来限制您的查询.此外,我认为您不能查询上次更新数据库的时间。如果保存了时间戳,则可以检查数据结构中的最后一个节点,但也可以只获取最新数据。

你想要这样的东西:

ref.child("yourChild").queryLimited(toLast: 7).observeSingleEvent(of: .value, with: { snap in
    // do something
})

根据您编写数据的方式,您需要 toLasttoFirst。假设最新的数据是最后写入的 toLast 就是你想要的。另请注意,我限制的数字是任意的,您可以使用适合您的项目的任何数字。

如果你已经有了一个键并且你想在那个键之上开始查询你可以这样做:

ref.child("YourChild").queryOrderedByKey().queryEnding(atValue: lastVisiblePostKey).queryLimited(toLast: 8).observeSingleEvent(of: .value, with: { snap in
    // do something with more posts
})

您可能还想查看 this question , this questionpagination .

关于ios - Firebase:下次应用程序启动时如何只检索更改的项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48086657/

相关文章:

ios - 如何在 SwiftUI 中使用 DatePicker 创建警报

javascript - iPhone img 加载失败

java - 照片由相机上传异常(Firebase 存储)

javascript - Firebase Js 如何将值数组存储到各自键的每一行中

android - 如何重新启动应用程序一次 - Firebase

ios - 使用Swift将数据写入Firebase

ios - 如何在 Swift 中为多个 UIActionSheet 创建通用方法

javascript - 从网络应用程序调用 FB.login() 时,官方 Facebook iOS 应用程序总是崩溃

java - Android Studio) list 合并失败

ios - Xcode Firebase 崩溃报告权限被拒绝