android - ChildEventListener 不一致?

标签 android firebase firebase-realtime-database

我一直在使用 Firebase Android Api 并发现了这个功能(在我看来这不一致)。我想针对它在我的场景中引起的问题征求意见和/或解决方案。

在 Android 应用程序中,我以这种形式建立了一个标准的“ChildEventListener”:

new Firebase("https://[MYTEST].firebaseio.com/").addChildEventListener(
  new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot data, String prev) {
      Log.i("_", "add " + data);
    }
    @Override
    public void onChildChanged(DataSnapshot data, String prev) {
      Log.i("_", "chg " + data);
    }
    @Override
    public void onChildRemoved(DataSnapshot data) {
      Log.i("_", "del " + data);
    }
    @Override
    public void onChildMoved(DataSnapshot data, String prev) {
      Log.i("_", "mov " + data);
    }
    @Override
    public void onCancelled(FirebaseError err) {
      Log.i("_", "err " + err.getMessage());
    }
  }
);

工作起来很有魅力,可以捕获我可以从 Firebase 仪表板向其转换的所有事件。

下一步:

  • 停止并终止我的 Android 应用程序并通过仪表板添加一个键(几个键)。
  • 启动应用程序,“onChildAdded()”会 catch 已添加的所有内容。 (实际上给了我全套 - 正如 specked 和预期的那样)。我可以很容易地弄清楚添加了什么。 目前一切顺利
  • 我也尝试删除。通过仪表板停止并终止应用程序并删除一个 key (多个 key )。
  • 再次启动应用程序并再次获取“onChildAdded()”,其中包含实际数量的剩余节点,或者如果没有剩余节点则没有事件。
  • 这一次,我没有收到反射(reflect)应用停止运行时所发生情况的“onChildRemoved()”事件。

我知道此行为可能是设计使然,但即使我保留本地节点列表和简单差异可能会给我一组已删除的节点,它也会带来问题。但事实是,空节点列表不会生成“onChildAdded()”事件,因此很难放置计算已删除节点的代码。

我想还有另一种方法可以解决这个“死时删除”的问题,请向我指出正确的方向。

最佳答案

总结:Firebase 数据库同步状态。与消息传递机制不同,它不同步状态更改。

当您启动一个没有缓存 Firebase 数据库数据的应用时,Firebase API 会同步您的应用与存储信息同步所需的最少数据。因此,对于当时服务器上存在的任何数据,您将获得一个 child_added 事件。

如果您的应用程序在连接时已经从数据库中获取了以前的信息(例如,当您使用 Firebase 的磁盘持久性时,或者当您的连接在没有重新启动应用程序的情况下恢复时),API 将触发获取所需的事件数据的本地版本与服务器同步。因此,在这种情况下,您可能会看到 child_addedchild_changedchild_movedchild_removed 事件。

无法保证在您的客户端未连接时传输状态更改。

实践中的状态同步

一个这样的例子:

  • 上网
  • 获取所有数据
  • 下线
  • 另一个用户增加了值(value)A
  • 另一个用户删除了值 A
  • 再次上网

您的应用现在不会收到任何表明值 A 曾经存在的指示。这就是状态同步的工作方式。

存储状态变化,而不是状态

如果您的应用要求每个客户端都知道每个状态更改,您应该将实际状态更改存储在数据库中。

  • 上网
  • 获取所有数据
  • 下线
  • 另一个用户写记录“增加值(value)A”
  • 另一个用户写记录“删除值A”
  • 再次上网

客户端现在将接收所有状态更改,因为您将这些更改存储在数据库中。

通常,您还希望运行一个可信进程,将所有状态更改记录再次聚合到一个“当前状态”中,以便更快地访问。

关于android - ChildEventListener 不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34371704/

相关文章:

Swift:从 Firebase 检索数据并在 TableView 中显示

android - 在 Kotlinx 序列化中使字段可选

java - 使用 Jackson 反序列化泛型

javascript - Firebase通过数组包含对象搜索数据库

ios - 从 Firebase Swift 加载后单元格不显示图像

java - 如何在android中的POJO中设置和获取 `ServerValue.TIMESTAMP`?

javascript - 使用 Firebase 和查询选择字段子集的 NoSQL 数据结构

添加 admob 后 Android 应用无法启动

java - xml中事件和标签的区别

ios - 单击带有 Reveal 的推送通知导航到特定 View