Firebase实时数据库EventListener重复调用致数据重复问题
问题分析与解决方案
你遇到的用户ID重复添加问题,根源很明确——多余的嵌套循环导致了重复处理。咱们来拆解下你的代码逻辑:
在onDataChange里,你已经通过第一个for循环把所有聊天列表的用户ID存入了UserChatList,但紧接着又套了一个for (int i =1;i<=UserListSize;i++)循环。这个外层循环完全没必要!它会让你遍历UserChatList的次数等于用户列表的长度(比如列表里有2个用户,就会遍历2次),自然每个用户ID会被重复请求和添加,最终导致mUsers里出现重复的用户对象。
另外还有个细节问题:UserChatList没有在每次获取数据前清空,如果后续聊天列表有更新,旧的ID会一直留在集合里,也可能引发重复。
修复后的代码
private void chatlist_loop(){ // 清空数据,避免重复累加 mUsers.clear(); UserChatList.clear(); // 新增:每次获取前清空聊天列表ID集合 mUserAdapter = new UserAdapter(getContext(), mUsers, false); recyclerView.setAdapter(mUserAdapter); mUserAdapter.notifyDataSetChanged(); String fuser = FirebaseAuth.getInstance().getCurrentUser().getUid(); rootRef = FirebaseDatabase.getInstance().getReference(); ChatlistRef = rootRef.child("Chatlist").child(fuser); mValueEventListener=new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot ds : dataSnapshot.getChildren()) { String userIDS = ds.getKey(); UserChatList.add(userIDS); Log.d(TAG,"Size for each loop "+UserChatList.size()); } // 去掉多余的外层for循环,直接遍历一次UserChatList即可 for (String usereReference:UserChatList) { Log.d(TAG,"User List Ids : " +usereReference); DatabaseReference UserRef= FirebaseDatabase.getInstance().getReference("Users").child(usereReference); ValueEventListener eventListener = new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { User user = dataSnapshot.getValue(User.class); // 可选:加判断避免重复添加(需确保User类重写了equals和hashCode) if(!mUsers.contains(user)){ mUsers.add(user); mUserAdapter.notifyDataSetChanged(); } String name = dataSnapshot.child("First").getValue(String.class); Log.d(TAG, "Name called "+name); } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // 建议添加错误日志,方便排查问题 Log.e(TAG, "获取用户数据失败", databaseError.toException()); } }; UserRef.addListenerForSingleValueEvent(eventListener); } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { Log.e(TAG, "获取聊天列表失败", databaseError.toException()); } }; ChatlistRef.addListenerForSingleValueEvent(mValueEventListener); }
关键修复点
- 移除多余的外层for循环:只需要遍历一次
UserChatList就能处理所有用户ID,不需要重复遍历。 - 清空
UserChatList:每次获取聊天列表前清空集合,防止旧数据残留导致重复。 - 可选重复判断:在添加用户到
mUsers前判断是否已存在(前提是User类正确重写了equals和hashCode方法),进一步避免重复。 - 添加错误日志:在
onCancelled中记录错误信息,方便后续排查问题。
这样修改后,每个用户ID只会被处理一次,重复添加的问题就解决了。
内容的提问来源于stack exchange,提问作者Ravi Malik
相关产品推荐
相关产品推荐

