我通过 Firebase 通知控制台向用户发送通知 Android 设备,我注意到,即使我在用户设备离线时发送了 10 条不同的通知,一旦用户上线,她/他也会收到所有 10 条通知。
但是,在Firebase文档中指出:
FCM 允许应用服务器在任何给定时间对每台设备最多使用四个不同的折叠键。换句话说,FCM 连接服务器可以同时为每个设备存储四个不同的可折叠发送同步消息,每个消息都有不同的折叠键。如果超过此数字,FCM 仅保留四个折叠键,无法保证保留哪些键。
那么用户不应该只收到 4 条通知吗?我错过了什么吗?(我不扩展FirebaseMessagingService
,我把通知处理留给SDK)
更新:如果您未在 Firebase 通知控制台中指定折叠键,则似乎为通知分配了一个隐式折叠键,即应用的软件包名称。我已经通过检查getIntent().getExtras()
键集的所有键/值对来测试这一点,一旦我通过点击通知启动应用程序。事实上,即使我没有指定包名称的值,我也得到了一个带有包名称值的collapse_key
密钥。
更新2:我尝试通过扩展FirebaseMessagingService
来处理通知,以便在应用程序处于前台时从通知控制台接收消息。我收到通知消息,并手动向用户显示通知。你猜怎么着。折叠键效果很好!即使我使用相同的折叠键发送多个通知,我也会收到单个通知。但是,这显然仅在应用处于前台时才会发生,因为当应用处于后台时,Firebase SDK 不会调用onMessageReceived()
,而是自行处理通知。这是否意味着这是Firebase SDK的错误?(因为仅当 SDK 显示通知时才会出现问题)
所以问题仍然存在,为什么我会收到所有 10 个通知,因为每个通知都有相同的折叠键?也许是FCM错误?
阅读帖子和评论后,我并不完全清楚已经尝试过的所有内容,哪些努力是成功的,哪些是失败的。 我会介绍一些项目,希望有所帮助。
您的帖子表明,对于某些测试,您在 Firebase 控制台中撰写消息时指定了折叠键。 这是不可能的。 如果您打开了高级选项并在自定义数据下输入了键/值对,则不起作用。 这些值存储在消息中的data
键下,而不是存储在必须显示collapse_key
的消息的顶层。此外,文档中的表 1 包括一个警告,即data
键不应是表中的任何保留字,并特别引用了collapse_key
:
密钥不应是保留字("from"或任何以 使用"谷歌"或"GCM")。请勿使用此处定义的任何单词 表(如collapse_key)。
如帖子评论中所述,控制台会自动分配一个折叠键,即包名称,因此用户不需要输入折叠键。
也就是说,我对控制台的体验与您的一致。 我通过仅输入消息文本和设备令牌来创建消息。 我没有看到折叠处理;设备接收每条消息。 根据我对下面描述的测试的经验,这似乎是控制台的问题,而不是一般的折叠处理问题。 这很奇怪,因为如果我在应用程序处于前台时发送消息,并且调用了onMessageReceived()
,我有调试日志记录,使用 getCollapseKey() 输出消息中的折叠键。 该输出确认密钥存在,并且是我的应用包名称。
您指示您执行了一些从云函数发送通知的测试。 我用这个云函数做了自己的测试,并观察到预期的消息崩溃:
exports.test = functions.database.ref('/test').onWrite(event => {
const token = 'dK1FjGbNr6k:APA91bH7Vz3x...icGO56sJ7rAqOXRI';
console.log('Sending notification...');
const payload = {
notification: {
title: 'Message',
body: 'Just one please!'
}
};
const options = {
collapseKey: 'green'
};
return admin.messaging().sendToDevice(token, payload, options).then(response => {
console.log('Done');
});
});
我还使用浏览器应用程序Advanced Rest Client发送了此消息,并且还看到正确的消息折叠:
{
"to": "dK1FjGbNr6k:APA91bH7Vz3x...O56sJ7rAqOXRI",
"collapse_key": "green",
"notification": {
"title": "Message",
"body": "Just one please!"
}
}
我还将分享Firebase在收到通知消息时发出分析日志消息。 当您想要获取收到的消息计数时,这对于测试很有用:
D/FA: Logging event (FE): notification_receive(_nr), Bundle[{firebase_event_origin(_o)=fcm, message_device_time(_ndt)=0, message_time(_nmt)=1498227476, message_id(_nmid)=6447126672094369335}]