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)
这似乎有效。当我重新启动应用程序时,我会得到更新的值。
但是我的问题是:应用程序是在每次应用程序启动时(我不想要这个)还是在需要更新时下载数据?
我设法让应用程序做我想做的事,尽管不可否认这可能不是最优雅的方式。
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)
| 归档时间: |
|
| 查看次数: |
2033 次 |
| 最近记录: |