Firebase云函数推送通知重复触发,消息通知数量递增问题求助
问题根源分析
你的核心问题出在ChatDetailActivity的sendNotification方法中错误使用了实时监听器:
- 代码中调用
firestore.collection("users").document(mUser.getUid()).addSnapshotListener(...),这会注册一个持续生效的实时监听器,每次调用sendNotification都会新增一个监听器实例,且这些监听器不会自动销毁。 - 当用户文档(users集合中当前用户的文档)发生任何变更(比如其他地方修改了用户信息),所有已注册的监听器都会被触发,重复向Notifications集合写入相同的消息文档。
- 云函数的
onCreate触发器会对每一条新增的Notifications文档推送通知,最终导致通知数量随消息发送次数累加(第n条消息触发n次推送)。
解决方案
将持续监听的addSnapshotListener替换为一次性获取数据的get()方法,因为你只需要在发送消息时获取一次用户的name和profilepic,不需要实时监听用户文档的变化:
修改后的ChatDetailActivity sendNotification方法
private void sendNotification(String recieverid, String body) { FirebaseFirestore firestore = FirebaseFirestore.getInstance(); // 使用get()一次性获取用户数据,避免重复监听 firestore.collection("users").document(mUser.getUid()).get() .addOnSuccessListener(value -> { if (value != null && value.exists()) { String name = value.getString("name"); String profilepic = value.getString("profilepic"); Map<String, Object> notification = new HashMap<>(); notification.put("userid", recieverid); notification.put("title", "Anonim Chat" + "&data" + senderid + "&data" + name + "&data" + profilepic); notification.put("body", name + ": " + body); firestore.collection("Notifications").document().set(notification) .addOnCompleteListener(task -> { if (task.isSuccessful()) { Log.w("test-message", "onComplete: bildirim başarıyla eklendi gönderildi"); } }) .addOnFailureListener(e -> Log.e("test-message", "onFailure: " + e.getLocalizedMessage())); } }) .addOnFailureListener(error -> { Log.e("test-message", "获取用户数据失败: " + error.getLocalizedMessage()); }); }
额外优化建议
- 通知ID唯一性:当前FirebaseMessagingService中使用固定的通知ID(
notify(1, ...)),新通知会覆盖旧通知。如果需要保留多条通知记录,可以使用唯一ID(比如消息的时间戳、随机数,或者从消息中提取唯一标识)。 - 监听器清理(若需使用实时监听):如果后续业务需要使用
addSnapshotListener,务必在Activity销毁时调用监听器的remove()方法,避免内存泄漏和重复触发:// 保存监听器实例 ListenerRegistration listenerRegistration; // 注册监听器 listenerRegistration = firestore.collection("users").document(mUser.getUid()).addSnapshotListener(...); // 在Activity的onDestroy方法中移除监听器 @Override protected void onDestroy() { super.onDestroy(); if (listenerRegistration != null) { listenerRegistration.remove(); } }
内容的提问来源于stack exchange,提问作者gkhnmr
相关产品推荐
相关产品推荐

