Firebase实时数据库:仅在驾驶员图片变更时推送Android通知
问题分析
当前代码的核心问题是没有对比驾驶员图片字段的前后值——只要当前drowsinessImage不是"--"就触发通知,而且每当驾驶员节点的任意字段(比如状态、分配信息等)变更时,onDataChange都会被调用,导致不必要的通知触发。
解决方案
要实现仅在图片变更时推送通知,需要记录每个驾驶员上次的图片值,并在数据更新时对比前后值,只有当值发生变化(且符合业务条件)时才发送通知。
步骤1:添加存储历史图片值的容器
在Activity类中定义一个HashMap,用来保存每个驾驶员ID对应的上次图片URL:
// 全局变量,映射驾驶员ID与对应历史图片URL private HashMap<String, String> driverLastImageMap = new HashMap<>();
步骤2:修改onDataChange逻辑
遍历驾驶员数据时,先获取当前驾驶员的唯一ID和图片值,与历史值对比后再决定是否触发通知:
public void onDataChange(@NonNull DataSnapshot snapshot) { drowsinessDriversList.clear(); adminUID = FirebaseAuth.getInstance().getCurrentUser().getUid(); // 移到循环外,避免重复获取 for (DataSnapshot dataSnapshot2 : snapshot.getChildren()) { String driverId = dataSnapshot2.getKey(); // 获取驾驶员节点的唯一ID driverModel = dataSnapshot2.getValue(DriverModel.class); // 处理列表更新逻辑 if (adminUID.equals(driverModel.getAssignTo()) && driverModel.getStatus().equals("Assigned")) { drowsinessDriversList.add(driverModel); Log.d("jawad", "arraylist.inner" + driverModel.getEmail()); } // 处理图片变更通知逻辑 String currentImage = driverModel.getDrowsinessImage(); String lastImage = driverLastImageMap.get(driverId); // 仅当历史值存在、当前值与历史值不同、且当前值不是"--"时,触发通知 if (lastImage != null) { if (!currentImage.equals(lastImage) && !currentImage.equals("--")) { Toast.makeText(AdminHomeActivity.this, "驾驶员图片已变更: " + currentImage, Toast.LENGTH_LONG).show(); notifyAdminDriverIsDrowsy(); } } // 更新历史图片值,下次对比使用 driverLastImageMap.put(driverId, currentImage); } recyclerView.setAdapter(driverDrowsinessAdapter); // 移到循环外,避免重复设置Adapter driverDrowsinessAdapter.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError error) { Log.e("jawad", "数据监听取消", error.toException()); }
关键优化点
- 减少冗余操作:将
adminUID的获取移到循环外,避免重复调用Firebase接口;Adapter设置也移到循环外,避免重复初始化。 - 精准匹配驾驶员:用
dataSnapshot2.getKey()获取驾驶员节点的唯一ID,确保每个驾驶员的历史图片值对应正确。 - 严格触发条件:只有当图片值确实发生变更时才发送通知,彻底避免任意字段变更导致的误触发。
内容的提问来源于stack exchange,提问作者JAWAD KHAN
相关产品推荐
相关产品推荐

