Ios Firebase:如何在下次应用程序启动时仅检索已更改的项目?

Ios Firebase:如何在下次应用程序启动时仅检索已更改的项目?,ios,firebase,firebase-realtime-database,Ios,Firebase,Firebase Realtime Database,我有一个使用Firebase db的应用程序,其中包含100000个项目。我的应用程序必须处理这些项目,这需要几秒钟的时间。 发生的情况是,每次启动应用程序(从终止状态)时,每次都会处理100000个项目(即使Firebase服务器上数据库的内容没有更改)。显然,如果没有必要,我不希望应用程序这样做。下面是一些代码: if dbRef == nil { FirebaseApp.configure(); Database.database().isPersistenceEnable

我有一个使用Firebase db的应用程序,其中包含100000个项目。我的应用程序必须处理这些项目,这需要几秒钟的时间。 发生的情况是,每次启动应用程序(从终止状态)时,每次都会处理100000个项目(即使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或类似的东西提供什么值来修改观测参数。 该数据库(不是我创建的,也不是我用新内容更新的)在一个平面结构中有100000个项目(即,一个家长有100000个孩子),自上次我的应用运行以来,这些孩子中的任何数量都可能被删除和替换,但总数仍然是100000。没有一个孩子有明确的时间戳或类似的东西

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

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

更新

因此,您可以通过以下方式设置用户上次连接到服务器的时间戳:

lastOnlineRef.onDisconnectSetValue(ServerValue.timestamp())
看一看Frank解释了一些关于持久性和听众的问题。问题是Android,但原则是一样的

我仍然认为问题在于你的质疑。因为您已经保存了数据
。值
不是您想要的,因为它返回所有数据

我想您想在查询中附加一个
.childChanged
侦听器。在这种情况下,查询将只返回已更改的数据。如果您没有听说过
.childchange
,请在阅读之前进行更改

我没有意识到这个问题与持久性有关。我想您正在寻找
keepSynced()
。看一看

原始答案

问题在于你的疑问。你要的是所有的数据,这就是为什么你要得到所有的数据。您希望研究如何使用限制查询。此外,我认为您无法查询数据库上次更新的时间。如果保存了时间戳,则可以检查数据结构中的最后一个节点,但也可以只获取最新数据

你想要这样的东西:

ref.child("yourChild").queryLimited(toLast: 7).observeSingleEvent(of: .value, with: { snap in
    // do something
})
根据您编写数据的方式,您需要
toLast
toFirst
。假设最新数据是最后写入的
toLast
就是您想要的。还请注意,我限制的数字是任意的,您可以使用适合您的项目的任何数字

如果您已经有一个密钥,并且希望开始在该密钥上方查询,则可以执行以下操作:

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

您可能还想查看和。

谢谢,但我不知道有多少数据可能已更改,因此不知道为toLast之类的东西提供什么价值。该数据库(不是我创建的,也不是我用新内容更新的)在一个平面结构中有100000个项目(即,一个家长有100000个孩子),自上次我的应用运行以来,这些孩子中的任何数量都可能被删除和替换,但总数仍然是100000。没有一个孩子有明确的时间戳或类似的东西。我的印象是Firebase可以在手机上保留数据的本地缓存,下次它与服务器同步时,它只会同步已更改的内容。因此,为了做到这一点,Firebase本身必须在内部具有一些增量信息,因此我希望增量信息可以以某种形式提供给我的应用程序。我想你正在寻找KeepSync()。看看这里:我一直在尝试keepSynched()的一些实验,但似乎并没有解决问题。您能更新您的问题以包含keepSynched()的代码吗?