如何解决Ionic安卓应用推送TTL过期后仍送达的问题?
首先得明确一个核心逻辑:FCM的time_to_live参数只有当设备离线时才会生效——如果设备在消息发送时处于在线状态,FCM会立即推送,不会等待TTL过期。所以先确认你的测试场景是:让设备离线后发送消息,等待超过3600秒再让设备上线,再观察是否收到消息。如果是设备一直在线的情况,消息立刻送达是完全正常的。
如果测试场景没问题,那可以从以下几个方向逐一排查:
1. 确认time_to_live参数的位置是否正确
在你使用的FCM Legacy API(https://fcm.googleapis.com/fcm/send端点)中,time_to_live是顶级JSON字段,绝对不能嵌套在notification或data对象里。如果你的PHP代码把它放在了子对象中,FCM会直接忽略这个参数。
正确的请求体数组结构应该是这样的:
$fields = array( 'to' => $your_device_token, 'time_to_live' => 3600, // 必须是根数组的直接字段 'notification' => array( 'title' => '你的推送标题', 'body' => '你的推送内容' ), // 自定义数据放在这里(可选) 'data' => array( 'custom_key' => 'custom_value' ) );
仔细检查你代码中的数组层级,确保time_to_live没有被错误嵌套。
2. 验证FCM是否正确接收了TTL参数
发送推送后,查看FCM返回的响应内容,或者登录Firebase控制台,在Cloud Messaging模块中找到对应的消息记录,检查time_to_live是否被正确识别并设置。
如果响应没有报错,但TTL参数未生效,可能是你的请求头或JSON格式有问题——务必确保请求头包含Content-Type: application/json,且发送的是标准的JSON格式。
3. 排查设备端的厂商推送通道干扰
部分安卓厂商(如小米、华为、OPPO)有自己的定制推送通道,可能会绕过FCM的TTL规则,强制缓存消息。这种情况下,你需要:
- 在设备的应用权限中开启“允许后台活动”“允许推送通知”等权限;
- 若有必要,适配厂商的原生推送服务(不过这一步成本较高,优先排查前面的点)。
4. 检查Ionic推送插件的配置
如果你使用的是@capacitor/push-notifications或旧版cordova-plugin-fcm这类Ionic推送插件,确保插件没有覆盖或忽略FCM的TTL设置。一般来说插件只是负责传递消息到应用,不会干预服务器端的TTL逻辑,但可以查看插件文档确认是否有相关配置项影响消息缓存。
5. 备选方案:升级到FCM HTTP v1 API
如果Legacy API的问题始终无法解决,可以尝试升级到FCM HTTP v1 API,它的参数结构更清晰,ttl参数放在android配置下:
{ "message": { "token": "DEVICE_TOKEN", "android": { "ttl": "3600s" // 注意这里是带单位的字符串格式 }, "notification": { "title": "测试标题", "body": "测试内容" } } }
不过升级需要调整PHP代码的认证方式(使用服务账号密钥),可以作为最后的尝试方向。
内容的提问来源于stack exchange,提问作者GunarathneMDD




