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

恢复网络后FCM通知无法稳定送达的问题求助

问题:Android设备断网恢复后FCM Web Push通知送达不稳定

我在Web应用中集成了FCM Web Push实现通知功能,目前处于测试阶段,已在多台Android和Windows设备的Chrome、Edge浏览器上验证。用户订阅推送时会注册Service Worker,设备在线且网络正常时能立即接收通知,但Android设备断网后恢复连接时,通知送达情况随机:有时全部收到,有时完全收不到,有时仅收到部分。发送通知后FCM返回所有Token成功,说明消息已送达FCM服务器,但设备端存在丢通知的情况。


前台接收通知代码

var firebaseConfig = {
    apiKey: "",
    authDomain: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: ""
};
firebase.initializeApp(firebaseConfig);

fcmMessaging = firebase.messaging();

fcmMessaging.onMessage((payload) => {
        cuteToast({
            type: 'success',
            message: payload.notification.body,
            timer: 5000
        });
});

Service Worker代码(firebase-messaging-sw.js)

importScripts("https://www.gstatic.com/firebasejs/9.9.4/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/9.9.4/firebase-messaging-compat.js");

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
const app = firebase.initializeApp({
    apiKey: "",
    authDomain: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: ""
});

const messaging = firebase.messaging();

注:未重写onBackgroundMessage(),使用默认推送通知逻辑处理。

PHP发送通知代码

$url = 'https://fcm.googleapis.com/fcm/send';

$fields = json_encode(array ( 
    'registration_ids' => $tokens,
    'notification' => array (
        'title'=>$subject."-".date("H:i d.m.Y"),
        'body'=>br2nl($message,""),
        'icon'=>'./bug.png',
        'click_action'=>$clickUrl
    ),
    'data'=>array(
        'click_action'=>$clickUrl
    ),
    'priority'=>'high',
    'time_to_live'=>86400,
    'webpush'=>array(
            'headers'=>array(
                'TTL'=>86400,
                'Urgency'=>'High'
            )
    ),
    'android'=>array(
        'ttl'=>'86400s',
        'priority'=>'high'
    ),
    'apns'=>array(
        'header'=>array(
            'apns-priority'=>10,
            'apns-expiration'=>time() + 86400
        )
    )
));

$headers = array ( 
        'Authorization: key=',
        'Content-Type: application/json'
);

$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );

$result = json_decode(curl_exec ( $ch ));

curl_close ( $ch );

问题原因及解决方法

1. Web Push消息存储与系统限制

虽然设置了time_to_live和TTL为86400秒,但Android上的Chrome/Edge在设备长时间离线或深度休眠时,系统可能限制Service Worker唤醒,甚至清理缓存的推送消息。另外FCM对批量发送的消息可能合并或丢弃部分低优先级内容(即使标记了high优先级)。

解决方法:

  • 确保priority: high和Web Push的Urgency: High配置同时生效,避免系统忽略消息。
  • 关键通知拆分批量发送为单条发送,减少FCM合并消息的概率。

2. Service Worker激活状态异常

Android设备断网恢复后,Service Worker可能因长时间无活动被浏览器终止,无法接收推送消息。

解决方法:

  • 显式定义onBackgroundMessage()方法,确保Service Worker在后台消息到达时被唤醒:
messaging.onBackgroundMessage((payload) => {
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
    icon: payload.notification.icon
  };

  self.registration.showNotification(notificationTitle, notificationOptions);
});
  • 在Web应用前台添加定期心跳请求(比如每15分钟发送一个小请求),维持Service Worker活跃状态。

3. Android电池优化限制

Android的Doze模式、App Standby等电池优化功能会限制后台浏览器的网络访问与唤醒,导致消息无法送达或丢失。

解决方法:

  • 引导用户将Chrome/Edge添加到电池优化白名单,允许后台运行。
  • 改用data消息发送关键通知:notification消息由FCM客户端直接展示,data消息需Service Worker处理,系统对其唤醒限制更宽松。修改发送代码,将通知内容移至data字段,在Service Worker中处理展示逻辑。

4. FCM Token有效性问题

即使FCM返回发送成功,设备断网期间Token可能因浏览器清缓存、用户重新登录等失效,FCM不会立即返回失败,而是后续清理无效Token。

解决方法:

  • 添加Token刷新监听,及时更新后端存储的Token:
fcmMessaging.onTokenRefresh(() => {
  fcmMessaging.getToken().then((refreshedToken) => {
    // 将新Token发送到后端更新
  }).catch((err) => {
    console.log('获取新Token失败', err);
  });
});
  • 定期通过FCM API验证Token有效性,清理无效Token。

5. 消息合并导致丢失

FCM对同一设备的多条离线消息,可能按优先级合并,只保留最新的部分消息。

解决方法:

  • 为每条消息设置唯一的collapse_key,不同collapse_key的消息会被单独存储。如果需要保留所有消息,确保每条消息使用不同的collapse_key:
'collapse_key' => uniqid() // 添加到$fields数组中

内容的提问来源于stack exchange,提问作者Denis Fajertag

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:35:39