Firestore调用数据两次致RecyclerView条目重复问题求助
RecyclerView加载Firestore数据出现重复条目的解决方案
问题原因
你的代码中productList.clear()仅在调用loadData()时执行一次,但addSnapshotListener是实时监听,会在初始加载数据、后续Firestore数据发生变更时多次触发onEvent方法。每次触发时,你都会将ADDED类型的数据添加到列表中,却没有在每次处理数据前清空列表,导致旧数据未被清除,新数据不断追加,最终出现条目重复。
修改后的代码
private void loadData() { firestore.collection("Products").orderBy("order") .addSnapshotListener(new EventListener<QuerySnapshot>() { @SuppressLint("NotifyDataSetChanged") @Override public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) { // 处理错误情况 if(error != null) { if(progressDialog.isShowing()){ progressDialog.dismiss(); Log.e("Firestore gives server error", error.getMessage()); new Flashbar.Builder(requireActivity()) .gravity(Flashbar.Gravity.BOTTOM) .duration(500) .backgroundColorRes(com.margsapp.iosdialog.R.color.red) .messageColorRes(R.color.white) .showOverlay() .showIcon() .message("Something went wrong please try again later.") .build(); } return; // 出错后终止后续逻辑 } // 空值判断,避免崩溃 if (value == null) { if(progressDialog.isShowing()){ progressDialog.dismiss(); } return; } // 每次处理数据前清空列表,避免重复 productList.clear(); // 遍历所有文档变更,处理不同类型的操作 for (DocumentChange documentChange : value.getDocumentChanges()){ Product product = documentChange.getDocument().toObject(Product.class); switch (documentChange.getType()) { case ADDED: productList.add(product); break; case MODIFIED: // 找到对应条目并更新 int updateIndex = findProductIndex(product); if (updateIndex != -1) { productList.set(updateIndex, product); } break; case REMOVED: // 找到对应条目并删除 int removeIndex = findProductIndex(product); if (removeIndex != -1) { productList.remove(removeIndex); } break; } } productAdapter.notifyDataSetChanged(); if(progressDialog.isShowing()){ progressDialog.dismiss(); } } }); } // 辅助方法:根据产品唯一标识查找列表中的位置(需替换为你的Product类实际唯一字段,比如id) private int findProductIndex(Product product) { for (int i = 0; i < productList.size(); i++) { if (productList.get(i).getId().equals(product.getId())) { return i; } } return -1; }
关键修改点说明
- 将
productList.clear()移至onEvent方法内部,确保每次监听触发时先清空旧数据,再加载最新数据。 - 新增对
MODIFIED和REMOVED类型文档变更的处理,保证RecyclerView能同步响应Firestore的数据更新和删除操作。 - 增加
value == null的判断,替代原有的assert,避免空指针崩溃。 - 错误处理后添加
return,防止后续代码继续执行引发异常。
内容的提问来源于stack exchange,提问作者Mohammed Abid Nafi
相关产品推荐
相关产品推荐

