Firebase 持久化,清除 Firebase 缓存

Posted

技术标签:

【中文标题】Firebase 持久化,清除 Firebase 缓存【英文标题】:Firebase persistence, clear Firebase cache 【发布时间】:2014-08-16 11:32:47 【问题描述】:

我的应用使用 Firebase 同步和恢复数据。我使用setValue:withCompletionBlock: 方法插入、更新和删除 Firebase 对象。每当有 CoreData 保存时都会调用此方法,从而将我的所有本地更改同步到 Firebase

- (void) setValue:(id)value withCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;

现在同步会将所有本地数据上传到 firebase,而 restore 会将本地数据替换为 firebase 数据。

- (void) observeSingleEventOfType:(FEventType)eventType withBlock:(void (^)(FDataSnapshot* snapshot))block;

我观察FEventTypeValue并使用FDataSnapshot从Firebase获取数据并恢复本地数据。

所以在我将 persistence 设置为 Firebase 之前,一切对我来说都很完美。

[Firebase setOption:@"persistence" to:@YES];

现在当persistence 开启时,当我更新时,说在Firebase 中插入一个对象,然后恢复,插入之前的数据就会恢复。即新插入的对象不会被恢复。但是,如果我再次恢复,则插入的对象将被恢复。删除对象时也会发生同样的事情。删除的对象在我第一次恢复时重新出现,在我再次恢复时消失。我可以通过 Firebase 数据视图看到 Firebase 对象已正确插入和/或删除。

我不确定我在这里做错了什么。我只有在恢复时才有问题。我认为 Firebase 缓存导致了这个恢复问题。我正在考虑在恢复之前清除 Firebase 缓存。我的问题是

    在恢复之前清除缓存是个好方法吗? 如果是,如何清除 Firebase 缓存? 如果没有,您能否建议我恢复数据的最佳方法。

【问题讨论】:

【参考方案1】:

[注意:如果您可以选择使用 Cloud Firestore 而不是实时数据库,则它具有更好的离线支持。当您执行 .get() 时,它会自动尝试从服务器获取最新数据,并且仅在您离线时使用缓存数据。您还可以专门请求从服务器或缓存中检索数据。]

不幸的是,这是预期的行为。您可能可以通过使用 observeEventOfType 而不是 observeSingleEventOfType 来解决它

基本上,每当您观察数据时,我们都会首先从我们的持久缓存中提取数据。该数据将是我们上次从 Firebase 收到的任何数据。因为您使用的是 observeSingleEventOfType 而不是 observeEventOfType,所以您不会收到来自 Firebase 的定期更新,因此我们缓存的数据实际上不会包含您写入的最新数据。

作为一个简单的解决方法,您可以只在有问题的数据上添加一个 observeEventOfType。您实际上不需要对事件做任何事情。但是,如果您一直在听它们,那么您的应用将从 firebase 获取最新数据,并且当您调用 observeSingleEventOfType 时,您可以确信它会缓存最新数据。

【讨论】:

还是这样吗?似乎我遇到了这个问题。检查用户名是否存在,如果不存在,则创建用户。如果用户退出并尝试使用相同的用户名创建一个新用户,它将起作用,因为缓存没有得到更新。 我一直是 Firebase 的忠实粉丝。但是对于这一点,我不得不说老实说这是一个很大的限制。 Firebase 应该在方法fetchNewData: Bool 中添加一个新参数。意外的预期行为不是预期行为。在很多情况下这可能会失败,例如分页。我们大多数人在进行分页时不会对页面进行观察.value,否则可能会刷新上一页,并且分页概念本身(即减少数据传输)变得无用,因为观察方法不断刷新前一页数据,并且我们也不能使用removeObserver 有什么解决办法吗? 我不这么认为! 2年多还是这样! @michael-lehenbauer 你有修复的预计到达时间吗?【参考方案2】:

您可以使用snap.metadata.fromCache 标志来检查值是否来自缓存。请注意,如果缓存值和来自服务器的值匹配,除非您添加下面看到的 includeMetadataChanges 标志,否则它不会触发您的 onSnapshot 两次,相反,它只会触发一次,并将 metadata.fromCache 标志设置为 @987654324 @。

db.collection('users').doc(uid).onSnapshot( includeMetadataChanges: true , (snap) => 
   if (!snap.metadata.fromCache) 
        const user = snap.data();
        // Code here
    
)

【讨论】:

以上是关于Firebase 持久化,清除 Firebase 缓存的主要内容,如果未能解决你的问题,请参考以下文章

如何清除 Firebase 存储?

firebase_messaging 如何清除通知?

当我重新启动移动设备或此 android/firebase 应用程序时,Firebase 离线数据库数据被清除?*

Firebase Facebook 登录即使在卸载应用程序后清除缓存和注销

清除徽章依靠使用 firebase 的 RN 应用程序

Firebase 托管 Flutter Web 应用程序未清除首次部署的缓存