如果缓存数据已过时,是否可以仅从 Firebase 下载数据?

bkw*_*ero 5 firebase swift firebase-realtime-database

我的第一个带有 Firebase 的大型应用程序刚刚启动,但遇到了一个问题 - 我的下载带宽很快就用完了。

我研究了几个缓存数据的选项。我希望缓存的数据仅在它是最新的时才使用。如果自创建缓存以来 Firebase 上的数据已更新,我想重新下载所有数据。

我不希望在一个会话中多次更新数据。所以我想在获取新数据后立即删除观察者。

我尝试了两件事,但我不完全确定它们是如何工作的。

FIRDatabase.database().persistenceEnabled = true
Run Code Online (Sandbox Code Playgroud)

启用持久性很棒,因为只需一行代码即可缓存从 Firebase 下载的所有内容。即使应用程序未连接到互联网,它也会提取缓存数据并照常开展业务。

但我的问题是:当 Firebase 上的数据更新时,缓存会更新吗?情况似乎并非如此。

当我进入并更改 Firebase 上的值并重新启动应用程序时,它只给我缓存的值,而不是更新的值。

那么我试试这个:

ref.keepSynced(true)
Run Code Online (Sandbox Code Playgroud)

这似乎有效。当我重新启动应用程序时,我会得到更新的值。

但是我的问题是:应用程序是在每次应用程序启动时(我不想要这个)还是在需要更新时下载数据?

bkw*_*ero 3

我设法让应用程序做我想做的事,尽管不可否认这可能不是最优雅的方式。

1.) 我打电话persistenceEnabled进来didFinishLaunchingWithOptions。这会缓存从 Firebase 检索到的所有数据,以便在下次应用启动时立即使用。

2.) 我不调用keepSynced数据库参考。否则,应用程序将在每次加载应用程序时下载所有数据(不是我想要的)。

3.) 如果有新数据,则会处理两次 - 一次立即处理缓存数据,另一次在观察者检测到新数据时处理。第二次处理数据后,我删除了观察者。我使用计数器来判断这是第一次还是第二次处理数据。

4.) 如果没有新数据,则仅处理一次,并且不下载任何内容。

这实际上允许我仅在设备上缓存的数据已过时时才下载数据。否则使用缓存的数据。

这是一些代码来演示:

// First download is cached data, second one is updated live data if there is updated data on Firebase

    var timesDownloaded = 0

    func downloadPops(andOnCompletion completion:@escaping ()->()){

        let baseRef = FIRDatabase.database().reference().child("SomeChild")

        baseRef.observe(.value, with: { snapshot in

            if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {

                self.timesDownloaded+=1

                // Handle the data

            }

            // First download is cached data, second one is updated live data if there is updated data on Firebase

            if self.timesDownloaded > 1 {

                print("Showing updated data")

                baseRef.removeAllObservers()

            } else {

                print("Showing cached data")

            }

            completion()

        })

    }
Run Code Online (Sandbox Code Playgroud)