ChildEventListener不一致?

时间:2015-12-19 14:12:06

标签: 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()'赶上已添加的所有内容。 (实际上给了我全套 - 有斑点和预期)。我可以很容易地弄清楚添加了什么。 到目前为止很好
  • 我尝试删除相同的内容。停止并杀死应用程序并通过仪表板删除密钥(许多密钥)。
  • 再次启动应用程序并再次获取'onChildAdded()'并留下实际数量的节点,或者如果没有节点左下,则不会发生任何事件。
  • 这一次,我收到'onChildRemoved()'EVENT,它会反映应用程序死机时发生的事情。

据我所知,这种行为可能是设计的,但即使我保留了本地节点列表并且简单差异可能会给我一组已删除的节点,它也会出现问题。但事实上,一个空的节点列表没有生成'onChildAdded()'事件,因此很难放置计算已删除节点的代码。

我认为还有另一种方法来解决这个'删除而死'的问题,请在正确的方向上推动我。

1 个答案:

答案 0 :(得分:1)

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

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

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

无法保证在未连接客户端时状态发生变化。

实践中的状态同步

这方面的一个例子:

  • 上线
  • 获取所有数据
  • 离线
  • 其他用户添加值A
  • 其他用户删除了值A
  • 再次上线

您的应用现在不会收到价值A曾经存在的任何迹象。这只是状态同步的工作方式。

存储状态更改,而不是状态

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

  • 上线
  • 获取所有数据
  • 离线
  • 另一位用户写入记录“add value A”
  • 另一位用户写入记录“删除值A”
  • 再次上线

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

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