如何获取Firebase群聊内评论过的用户详情并避免数据重复展示
问题解决方法
根本原因
你当前的逻辑是遍历群内所有历史消息,每拿到一条消息就把对应的发送者直接加入参与者列表,同一个用户发送多条消息时就会被多次添加到列表中,最终出现重复展示的问题。
修复方案
方式1:新增发送者判重逻辑(改动最小,无需修改原有实体类)
在遍历消息的过程中,用一个Set记录已经添加过的用户ID,只有未记录过的用户才加入列表:
DatabaseReference databaseReference3 = FirebaseDatabase.getInstance().getReference("Groups"); // 适配器只需要初始化一次,不要每次数据变化都重新创建,提前在onCreate等生命周期里完成初始化即可 // participantArrays = new ArrayList<>(); // adapter = new ParticipantsAdapter(participantArrays, GroupEdit.this); // recyclerView.setAdapter(adapter); // recyclerView.setHasFixedSize(true); databaseReference3.child(groupId).child("Messages").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { participantArrays.clear(); // 用来存储已经添加过的发送者ID,自动去重 Set<String> addedSenders = new HashSet<>(); for (DataSnapshot dataSnapshot: snapshot.getChildren()){ ParticipantArray array = dataSnapshot.getValue(ParticipantArray.class); if(array.getSender() != null && !addedSenders.contains(array.getSender())) { addedSenders.add(array.getSender()); participantArrays.add(array); } } // 直接通知适配器数据更新即可,不用重复创建适配器 adapter.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError error) { // 建议添加错误日志打印,方便排查问题 Log.e("FirebaseError", error.getMessage()); } });
方式2:重写实体类的equals和hashCode方法(适合后续其他场景也需要按用户去重的情况)
修改ParticipantArray类,以sender作为唯一判断标准:
public class ParticipantArray { String sender; String msg; public ParticipantArray(String sender, String msg) { this.sender = sender; this.msg = msg; } public ParticipantArray(){} public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getSender() { return sender; } public void setSender(String sender) { this.sender = sender; } // 重写equals,仅判断sender是否相同 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ParticipantArray that = (ParticipantArray) o; return Objects.equals(sender, that.sender); } // 重写hashCode,仅用sender生成hash值 @Override public int hashCode() { return Objects.hash(sender); } }
之后直接用HashSet接收所有数据再转成List即可实现去重:
@Override public void onDataChange(@NonNull DataSnapshot snapshot) { Set<ParticipantArray> participantSet = new HashSet<>(); for (DataSnapshot dataSnapshot: snapshot.getChildren()){ ParticipantArray array = dataSnapshot.getValue(ParticipantArray.class); if(array.getSender() != null) { participantSet.add(array); } } participantArrays.clear(); participantArrays.addAll(participantSet); adapter.notifyDataSetChanged(); }
额外优化建议
不要每次数据回调都重新创建适配器、重新绑定RecyclerView,只需要在页面初始化时创建一次适配器,后续数据变更时直接调用notifyDataSetChanged刷新即可,能减少不必要的性能消耗。
内容的提问来源于stack exchange,提问作者Ijeoma
相关产品推荐
相关产品推荐

