32

我的应用使用 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 缓存。我的问题是

  1. 在恢复之前清除缓存是一种好方法吗?
  2. 如果是,如何清除 Firebase 缓存?
  3. 如果没有,你能建议我恢复数据的最佳方法吗?
4

2 回答 2

26

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

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

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

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

于 2014-07-01T18:23:54.637 回答
2

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

db.collection('users').doc(uid).onSnapshot({ includeMetadataChanges: true }, (snap) => {
   if (!snap.metadata.fromCache) {
        const user = snap.data();
        // Code here
    }
})
于 2019-05-16T15:58:34.083 回答