FirebaseUI结合Firebase Database查询多用户仅显示最后一个求助
我来帮你解决这个FirebaseUI只显示最后一个用户的问题!咱们先搞清楚问题出在哪,再一步步修改代码。
问题根源分析
你当前的代码里,每次onChildAdded触发时都会新建一个FirebaseRecyclerAdapter,然后直接设置给RecyclerView。这就相当于每次有新的用户ID进来,就用新的adapter覆盖掉之前的,最后RecyclerView自然就只显示最后一次查询到的用户了。
解决方案思路
我们需要先把所有需要展示的用户ID收集起来(还要去重,避免重复显示同一个用户),然后基于这个ID集合做一次批量查询,再用FirebaseUI渲染所有结果。如果后续有用户ID新增/移除,再实时更新查询即可。
修改后的完整代码
public class UserMessageListFragment extends Fragment { private ProgressDialog progressDialog; private final String TAG = "UsersMessageList"; private RecyclerView mResultList; private ArrayList<String> arrayUsers = new ArrayList<>(); // 用来存所有需要展示的用户ID private FirebaseRecyclerAdapter<User, UsersViewHolder> firebaseRecyclerAdapter; // 把adapter设为成员变量,方便后续更新 public static UserMessageListFragment newInstance() { return new UserMessageListFragment(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_user_message_list, container, false); mResultList = view.findViewById(R.id.message_list); mResultList.setHasFixedSize(true); mResultList.setLayoutManager(new LinearLayoutManager(mResultList.getContext())); final DatabaseReference refMessages = FirebaseDatabase.getInstance().getReference(); final DatabaseReference ref= FirebaseDatabase.getInstance().getReference().child("usuarios"); refMessages.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { if(dataSnapshot.getKey().contains(UserDetails.username+ "_")) { String[] userChatWithId = dataSnapshot.getKey().split(UserDetails.username+"_"); String targetUserId = userChatWithId[1]; // 避免重复添加同一个用户ID if(!arrayUsers.contains(targetUserId)){ arrayUsers.add(targetUserId); updateFirebaseUiQuery(ref); // 更新查询并刷新列表 } } } @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) { // 消息更新时同步检查用户ID if(dataSnapshot.getKey().contains(UserDetails.username+ "_")) { String[] userChatWithId = dataSnapshot.getKey().split(UserDetails.username+"_"); String targetUserId = userChatWithId[1]; if(!arrayUsers.contains(targetUserId)){ arrayUsers.add(targetUserId); updateFirebaseUiQuery(ref); } } } @Override public void onChildRemoved(DataSnapshot dataSnapshot) { // 消息删除时,移除对应的用户ID(可以额外检查是否还有其他消息关联该用户,这里简化处理) if(dataSnapshot.getKey().contains(UserDetails.username+ "_")) { String[] userChatWithId = dataSnapshot.getKey().split(UserDetails.username+"_"); String targetUserId = userChatWithId[1]; arrayUsers.remove(targetUserId); updateFirebaseUiQuery(ref); } } @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) { } @Override public void onCancelled(DatabaseError databaseError) { Log.e(TAG, "数据库查询失败", databaseError.toException()); } }); return view; } private void updateFirebaseUiQuery(DatabaseReference userRef){ if(arrayUsers.isEmpty()){ // 没有用户时清空列表 if(firebaseRecyclerAdapter != null){ firebaseRecyclerAdapter.stopListening(); mResultList.setAdapter(null); } return; } // 批量查询所有目标用户:使用Firebase的in操作符(注意最多支持10个ID) Query firebaseSearchQuery = userRef.orderByChild("username").in(arrayUsers); FirebaseRecyclerOptions<User> options = new FirebaseRecyclerOptions.Builder<User>() .setQuery(firebaseSearchQuery, User.class) .build(); if(firebaseRecyclerAdapter == null){ // 第一次初始化adapter bindAndBuildFirebaseUi(options); } else { // 已有adapter时,直接更新查询选项 firebaseRecyclerAdapter.updateOptions(options); } } public void bindAndBuildFirebaseUi(FirebaseRecyclerOptions options) { firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<User, UsersViewHolder>(options) { @Override public UsersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_list_layout, parent, false); return new UsersViewHolder(v); } @Override protected void onBindViewHolder(final UsersViewHolder holder, int position, final User model) { holder.bind(model); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { UserDetails.chatWithId = model.getUsername(); UserDetails.chatWith = model.getName(); startActivity(new Intent(getContext(), Chat.class)); } }); } }; firebaseRecyclerAdapter.startListening(); mResultList.setAdapter(firebaseRecyclerAdapter); } @Override public void onDestroyView() { super.onDestroyView(); // 页面销毁时停止监听,防止内存泄漏 if(firebaseRecyclerAdapter != null){ firebaseRecyclerAdapter.stopListening(); } } }
额外注意事项
in操作符的限制:Firebase Realtime Database的in查询最多支持10个值,如果你的用户ID超过10个,需要把集合分成多个10元素的子集分别查询,或者考虑改用Cloud Firestore(支持最多30个in值)。- 去重逻辑:添加用户ID时检查是否已存在,避免重复查询和显示同一个用户。
- 生命周期管理:在
onDestroyView中停止adapter的监听,这是避免内存泄漏的关键步骤。
内容的提问来源于stack exchange,提问作者user6246272
相关产品推荐
相关产品推荐

