动态更改Android

时间:2015-09-04 11:20:45

标签: java android firebase

我在我的Android应用程序中使用Firebase作为聊天功能。我打算支持的是:

  1. 每当新邮件到达或现有邮件更改或被删除时实时更新
  2. 无限向后滚动消息历史。
  3. 第一部分似乎很容易。我创建了一个带限制的firebase引用。

    ref = new Firebase(FIREBASE_URL).child("chat").limitToFirst(50);
    

    此引用随后由添加侦听器的适配器使用。然后在数据发生变化时修改List。

    ref.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {...}
        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {...}
        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {...}
        ...
    

    第二部分是我努力寻找正确方法的地方。 当用户到达列表末尾时,我想加载旧消息并将它们添加到消息列表中(无限滚动)。

    首选解决方案是简单地调用ref.changeLimitToFirst(100)之类的内容,但这种方法不存在。

    用firebase解决这个问题的最佳方法是什么?

    修改:

    我删除了我最初建议的解决方案,因为它们没有帮助澄清问题。相反,我将列出自我最初提出问题以来我发现的新解决方案。

    如果您知道更好,更优雅的方法,请留下答案!

    1. 最简单的方法似乎是从旧的Query中删除侦听器;然后使用新限制创建一个新查询。可以在this pull request中找到Firebase-UI-Android lib的示例。缺点是:
      • 添加新的侦听器后,您将收到每个子节点的child_added事件,而不仅仅是您尝试加载的事件。因此,在添加子列表之前,您必须检查子列表中是否已存在子项。这意味着如果列表变长,将会有很多次迭代。
      • 您不知道装载完成的时间。解决方法是添加一个额外的值侦听器,一旦加载了完整的快照,就会触发该侦听器(从而完成新页面的加载)。
    2. 第二种方法是通过监听value事件分别加载每个页面。不幸的是,offset()之类的东西不存在。所以要走的路是remember the last item you loaded and pass it to the startAt method。缺点:
      • 为了接收更新,您每次加载新页面时都需要删除旧的子监听器并添加新的监听器(因为限制更改)。然后,此侦听器将接收您必须过滤掉的child_added事件(参见上文)。
      • 最后一项的位置可能会在您加载第一页的时间与加载时间和添加第二页之间发生变化。如果您的数据顺序可能会发生变化,则无法确定您保存的子项是否是下一个查询的正确参考。在这种情况下,您需要再次使用子侦听器来接收先前加载的数据的更新。

1 个答案:

答案 0 :(得分:3)

在Firebase中,有两种方法可以检索数据:

1)通过EVENT观察节点

2)查询(在)特定数据的节点

这两个项目是独立的功能,但可以采用类似的方式运行,并且可以从Firebase检索数据。

使用Firebase查询,您可以根据各种因素有选择地检索数据。

问题的答案取决于数据的结构。假设这个结构

Msgs
  node_ref:
    index: 0
    msg: 'Hows the weather'
  node_ref:
    index: 1
    msg: 'Hot'

回答:1)实时更新

如果Msgs节点有一个监听器,则会通知应用程序对该节点的任何更改,并可用于加载该节点内数据的初始快照,然后监听该节点内的消息,更新和删除

根据您的更新,您可以加载前50个。但是,第2部分的答案可能是另一个解决方案。

回答:2)向后滚动(或向前滚动,或加载数据集)

添加侦听器与在Msgs节点上针对特定邮件执行Firebase查询无关。 Query将用于加载子索引为1的消息,或者子索引小于10的任何消息,或者包含从5开始到10结束的子索引的消息。

这可以通过范围查询来完成:使用startAt(),endAt()和equalTo()可以为查询选择任意的起点和终点。

因此,如果Msgs节点包含100条消息,并且显示子索引为90-99的消息,并且用户向后滚动(到较旧的消息),则可以进行简单的范围查询以查询消息80-89,其中然后将加载并显示。类似地,如果显示消息0-9(最旧的)并且用户向前滚动,则从消息10-19中搜索范围。

如您所见,利用Queries加载数据时根本不需要监听器。当有数据(添加,更新或删除)时,监听器将用于告诉应用

话虽如此,有些方法可以在没有查询的情况下执行此操作,但这取决于数据的结构以及UI的行为方式。