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

基于Firebase实现类WhatsApp的推送通知消息追加功能

实现类似WhatsApp的FCM合并通知功能

我来帮你捋清楚怎么用Firebase Cloud Messaging(FCM)实现这个类似WhatsApp的通知合并逻辑,核心是要结合FCM的通知标签(tag)和服务器端维护用户未读消息状态来完成,具体步骤和代码调整如下:

核心逻辑拆解

WhatsApp的通知规则本质是:

  • 用户未读当前会话的通知时,新消息追加到原有通知内容,不弹出新通知
  • 用户点击通知标记已读后,重置未读状态,后续新消息作为独立通知展示

要实现这个,你需要在服务器端为每个用户的每个会话(单聊/群聊)维护一个未读消息队列,配合FCM的tag属性复用同一个通知实例。


具体实现步骤

1. 服务器端维护未读消息状态

首先要在你的数据库里为每个用户的每个会话存储未读消息列表,比如用user_id + conversation_id作为联合键来关联。

当有新消息到来时,分两种情况处理:

  • 如果用户该会话没有未读消息(或已标记已读):发送独立通知,并将这条消息加入未读列表
  • 如果用户该会话已有未读消息:将新消息追加到未读列表,然后发送更新后的合并通知

2. 配置FCM关键参数

重点用好tag属性:

  • 给同一个会话设置固定的tag值(比如用会话ID作为tag),这样FCM会自动复用这个tag对应的通知,不会弹出新的通知窗口,只会更新原有通知的内容
  • collapseKey主要针对后台数据消息,通知类的合并逻辑核心靠tag,可以保留但不用作为重点

3. 处理用户点击通知的已读逻辑

当用户点击通知跳转到你的网页时,要在页面初始化时向服务器发送请求,标记该会话的未读消息为已读,服务器收到请求后清空对应会话的未读消息列表。


修改后的代码示例

服务器端发送通知的PHP代码

// 假设你已经从数据库获取到接收消息的用户ID、会话ID,以及新消息内容
$userId = "接收消息的用户ID";
$conversationId = "当前会话的ID(单聊/群聊ID)";
$newMessageContent = "message2"; // 新收到的消息内容
$fcmToken = $key; // 用户的FCM推送令牌

// 从数据库获取该用户该会话的未读消息列表
function getUnreadMessages($userId, $conversationId) {
    // 这里写你的数据库查询逻辑,返回未读消息数组
    return [];
}

// 更新数据库中的未读消息列表
function updateUnreadMessages($userId, $conversationId, $messages) {
    // 这里写你的数据库更新逻辑
}

// 获取当前未读消息
$unreadMessages = getUnreadMessages($userId, $conversationId);

// 构建通知内容
if (empty($unreadMessages)) {
    // 无未读消息,发送独立通知
    $notificationTitle = "新消息";
    $notificationBody = $newMessageContent;
    $unreadMessages[] = $newMessageContent;
} else {
    // 有未读消息,合并内容
    $unreadMessages[] = $newMessageContent;
    $notificationTitle = count($unreadMessages) . "条新消息";
    $notificationBody = implode("\n", $unreadMessages); // 用换行拼接所有未读消息
}

// 更新未读消息到数据库
updateUnreadMessages($userId, $conversationId, $unreadMessages);

// 构建FCM请求数据
define( 'API_ACCESS_KEY', 'AAAAlHKlaCE_______________________-NdJXkojLf9Ap9mu' ); 
$data = array(
    "to" => $fcmToken, 
    "priority" => "normal", 
    "notification" => array( 
        "title" => $notificationTitle, 
        "body" => $notificationBody, 
        "icon" => "../profiles/p1.jpg", 
        "tag" => $conversationId, // 用会话ID作为tag,确保同一个会话的通知复用
        "click_action" => "http://website.com?conversationId=" . $conversationId // 把会话ID传到页面
    )
); 

$data_string = json_encode($data); 
$headers = array (
    'Authorization: key=' . API_ACCESS_KEY,
    'Content-Type: application/json' 
); 

$ch = curl_init(); 
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' ); 
curl_setopt( $ch,CURLOPT_POST, true ); 
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers ); 
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true ); 
curl_setopt( $ch,CURLOPT_POSTFIELDS, $data_string); 
$result = curl_exec($ch); 
curl_close ($ch); 

前端处理已读的JavaScript代码

在click_action指向的页面中,添加以下逻辑:

// 从URL参数中获取会话ID
const urlParams = new URLSearchParams(window.location.search);
const conversationId = urlParams.get('conversationId');
const currentUserId = "当前登录用户的ID"; // 从你的登录状态中获取

// 向服务器发送已读标记请求
fetch('/api/mark-unread-as-read', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        userId: currentUserId,
        conversationId: conversationId
    }),
})
.then(response => response.json())
.then(() => {
    console.log("未读消息已标记为已读");
})
.catch(err => console.error("标记已读失败:", err));

服务器端处理已读请求的PHP接口

// /api/mark-unread-as-read 接口逻辑
$input = json_decode(file_get_contents('php://input'), true);
$userId = $input['userId'];
$conversationId = $input['conversationId'];

// 清空该用户该会话的未读消息列表
function clearUnreadMessages($userId, $conversationId) {
    // 这里写你的数据库更新逻辑,清空对应未读消息
}

clearUnreadMessages($userId, $conversationId);

echo json_encode([
    'status' => 'success',
    'message' => '未读消息已清空'
]);

额外注意事项

  • Tag的唯一性:不同会话必须用不同的tag值,避免不同聊天的通知互相合并干扰
  • 通知体验优化:可以在消息内容前加上发送者昵称,比如"张三: 今晚一起吃饭?\n李四: 好的,几点?",更贴近WhatsApp的样式
  • 前台消息处理:如果你的Web应用在前台运行,需要在Service Worker中监听notificationclick事件,同样触发已读标记逻辑
  • 数据库原子性:处理并发消息时,要确保未读消息的更新是原子操作,避免消息丢失

内容的提问来源于stack exchange,提问作者Ahsan Ahmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:05:17