Firebase查询n项并仅收听新内容

时间:2017-03-25 20:32:27

标签: android firebase-realtime-database

我正在尝试查询最后5个项目,然后只收听新的孩子。然而, 当我添加新的孩子时,childeventlistener会返回我之前查询过的最后一个孩子。

query = myRef.orderByKey().limitToLast(5);
    query.addListenerForSingleValueEvent(new ValueEventListener() {
      @Override public void onDataChange(DataSnapshot dataSnapshot) {
        if (dataSnapshot.exists()) {
          // dataSnapshot is the "issue" node with all children with id 0
          int oldSize = mData.size();
          List<ChatMessageEntity> data = new ArrayList<>();
          for (DataSnapshot issue : dataSnapshot.getChildren()) {
            // do something with the individual "issues"
            ChatMessageEntity chat = issue.getValue(ChatMessageEntity.class);
            data.add(0,chat);
          }
          mData.addAll(data);
          adapter.notifyItemRangeInserted(oldSize, mData.size());
        }

        query.addChildEventListener(newMessageListener);
      }

      @Override public void onCancelled(DatabaseError databaseError) {

      }
    });

2 个答案:

答案 0 :(得分:1)

使用此类方案,您最好使用ChildEventListener。这有一个方法onChildAdded,最初将调用(最多)五个孩子,然后为后来添加的每个新孩子调用。

query = myRef.orderByKey().limitToLast(5);
query.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
        ChatMessageEntity chat = issue.getValue(ChatMessageEntity.class);
        data.add(0,chat);
        adapter.notifyItemInserted(mData.size()-1);
    }

    ...

    @Override public void onCancelled(DatabaseError databaseError) {
        throw databaseError.toException(); // don't ignore these
    }
});

上述代码有效,但缺少对previousChildName的处理(因为稍后到达的子项可能不会添加到列表的末尾),onChildChangedonChildMoved和{{ 1}}。为所有这些添加处理是一项有趣的练习,但是相当多的工作并且有点棘手。如果你想完成这项工作,我建议你看一下RecyclerViewAdapter in FirebaseUI及其工作马FirebaseArray - 这些都经过了很好的战斗测试。

有关详细信息,请参阅Firebase documentation on listening for child event

答案 1 :(得分:0)

我最好的补充是加载所需数量的项目,保存最新项目的密钥。从列表中删除带有该键的项目。创建从最新的key开始的新查询,并将childEventListener添加到它。

query = myRef.orderByKey().limitToLast(20);
    query.addListenerForSingleValueEvent(new ValueEventListener() {
      @Override public void onDataChange(DataSnapshot dataSnapshot) {

        if (dataSnapshot.exists()) {
          // dataSnapshot is the "issue" node with all children with id 0
          int oldSize = mData.size();
          //List<ChatMessageEntity> data = new ArrayList<>();

          for (DataSnapshot issue : dataSnapshot.getChildren()) {
            // do something with the individual "issues"
            ChatMessageEntity chat = issue.getValue(ChatMessageEntity.class);
            chat.key = issue.getKey();
            mData.add(chat);
            //data.add(0, chat);

          }
          //mData.addAll(data);
        }
        Log.e("mcheck", "onDataChange:  " + mData.get(0).message);
        Query query;
        if (mData.size() > 0) {
          query = myRef.orderByKey().startAt(mData.get(mData.size() - 1).key);
          olderstKey = mData.get(0).key;
          mData.remove(mData.size() - 1);
          adapter.notifyItemRemoved(mData.size()-1);
          adapter.notifyItemRangeInserted(0, mData.size());
          //adapter.notifyDataSetChanged();
          query.addChildEventListener(newMessageListener);
        } else {
          myRef.addChildEventListener(newMessageListener);
        }

      }

      @Override public void onCancelled(DatabaseError databaseError) {

      }
    });