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

如何使用Firebase将多条通知合并为单条?

Firebase 实现多条通知合并的可行方案

我懂你现在的困扰——用collapse_key只有设备离线时才起作用,tag又会直接覆盖旧通知,都没法实现多条同类型通知合并展示的需求对吧?其实FCM本身没有直接的服务端API来自动合并多条通知,但咱们可以通过以下几种方式来实现:

1. 客户端手动维护通知计数(推荐灵活场景)

这种方式是让客户端来处理通知的合并逻辑,核心思路是:

  • 发送通知时,在payload里附带自定义标识(比如通知类型type: "order_update"、当前计数count: 1或者唯一的业务ID)
  • 客户端收到新通知后,先检查系统通知栏里是否已有同类型的通知
  • 如果存在,就更新原有通知的内容(比如把“1条订单更新”改成“2条订单更新”),同时更新计数;如果不存在,再新建通知

举个Android端的简单示例(Kotlin):

// 收到FCM消息后处理
fun handleNotification(data: Map<String, String>) {
    val notificationType = data["type"] ?: return
    val currentCount = data["count"]?.toInt() ?: 1

    // 检查是否已有同类型通知
    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    val existingNotifications = notificationManager.activeNotifications
        .filter { it.tag == notificationType }

    val updatedCount = if (existingNotifications.isNotEmpty()) {
        existingNotifications.first().extras.getInt("count", 0) + currentCount
    } else {
        currentCount
    }

    // 构建更新后的通知
    val notification = NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("订单更新")
        .setContentText("您有 $updatedCount 条新的订单消息")
        .setSmallIcon(R.drawable.ic_notification)
        .setTag(notificationType) // 用类型作为tag,方便找到同类型通知
        .setExtras(Bundle().apply { putInt("count", updatedCount) })
        .build()

    notificationManager.notify(notificationType, 1, notification)
}

2. 使用通知组(折叠展示多条通知)

如果希望用户既能看到汇总,又能展开查看每条通知的详情,可以用FCM的通知组功能:

  • Android:在payload的android.notification里添加group字段,同组的通知会自动折叠
  • iOS:在apns.payload.aps里添加thread-id字段,实现类似的分组折叠

服务端Node.js的payload示例:

const payload = {
  notification: {
    title: "订单更新",
    body: "您的订单已发货"
  },
  data: {
    type: "order_update"
  },
  android: {
    notification: {
      group: "ORDER_NOTIFICATIONS",
      groupSummary: false // 如果设为true,这条会作为组的汇总通知
    }
  },
  apns: {
    payload: {
      aps: {
        "thread-id": "ORDER_NOTIFICATIONS"
      }
    }
  },
  token: "DEVICE_TOKEN"
};

如果需要一个汇总通知,可以单独发一条groupSummary: true的通知,内容比如“您有3条订单更新”,其他同组通知会折叠在它下面。

3. 服务端预合并通知(适合批量场景)

如果你的业务允许直接发送汇总后的通知,可以在服务端先统计用户的未读通知:

  • 每次要发送新通知前,先查询数据库中该用户未发送的同类型通知数量
  • 直接发送一条汇总内容的通知(比如“您有5条新消息”),同时标记这些通知为已发送
  • 这种方式不需要客户端处理,但需要维护用户的通知状态

比如Node.js服务端的逻辑示例:

// 假设从数据库查询用户未读的订单更新数量
async function sendMergedNotification(userId, deviceToken) {
  const unreadCount = await db.collection("notifications")
    .where("userId", "==", userId)
    .where("type", "==", "order_update")
    .where("sent", "==", false)
    .count()
    .get();

  if (unreadCount.data().count === 0) return;

  const payload = {
    notification: {
      title: "订单更新",
      body: `您有 ${unreadCount.data().count} 条新的订单消息`
    },
    token: deviceToken
  };

  await admin.messaging().send(payload);

  // 标记这些通知为已发送
  await db.collection("notifications")
    .where("userId", "==", userId)
    .where("type", "==", "order_update")
    .where("sent", "==", false)
    .update({ sent: true });
}

为什么collapse_key和tag不符合需求?

再帮你理清楚这两个字段的作用:

  • collapse_key:仅当设备离线时,FCM会把同key的多条通知合并成一条发送给设备,设备在线时还是会逐条推送,所以没法实现在线时的合并
  • tag:在线时,新的同tag通知会直接覆盖旧的,相当于替换而不是合并,所以也不符合你的需求

你可以根据自己的业务场景选择最合适的方案——如果需要保留每条通知的详情,用通知组;如果只需要汇总提醒,客户端计数或者服务端预合并都可以。

内容的提问来源于stack exchange,提问作者Always Learner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:06:51