You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:37:08