使用 FCM 的 IOS 数据通知
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38166203/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IOS data notifications with FCM
提问by Shayan C
I am using FCM (firebase cloud messaging) to send "custom" data notifications to an IOS app. From what I understand, we use notification messages when you want FCM to handle displaying a notification on your app's behalf. And we use data messages when you just want to process the messages only in your app. It's by design.
我正在使用 FCM(firebase 云消息传递)向 IOS 应用程序发送“自定义”数据通知。据我了解,当您希望 FCM 代表您的应用处理显示通知时,我们会使用通知消息。当您只想在您的应用程序中处理消息时,我们会使用数据消息。这是设计使然。
Problem I am facing is that that Device/InstandID token is unique to installed app and not the user logged in the app. So to solve this, I am sending intended user tag in the data so it becomes a data message. Since the app handles the data notifications, the didReceiveRemoteNotification() callback is only fired when the app is opened and the notification is only shown than and not instantly when it's sent.
我面临的问题是 Device/InstandID 令牌对于已安装的应用程序是唯一的,而不是登录应用程序的用户。所以为了解决这个问题,我在数据中发送了预期的用户标签,使其成为数据消息。由于应用程序处理数据通知,didReceiveRemoteNotification() 回调仅在应用程序打开时触发,并且通知仅在发送时显示而不是立即显示。
My question is that can I send a custom data notification message and make it appear instantly even when the app is closed.
我的问题是我可以发送自定义数据通知消息并使其即使在应用程序关闭时也能立即显示。
This is the payload I am sending to FCM:
这是我发送给 FCM 的有效载荷:
{
registeration_ids : [<id_1>, <id_2>],
data : {
title : message_title,
body : message_body,
intended_user : message_user
}
}
In android FirebaseMessagingService.onMessageReceived()
is invoked even if the app is in the background but in ios didReceiveRemoteNotification()
is only invoked when the application is launched so no background messages will appear if you send a data message.
FirebaseMessagingService.onMessageReceived()
即使应用程序在后台,在 android 中也会调用,但在 iosdidReceiveRemoteNotification()
中仅在应用程序启动时调用,因此如果您发送数据消息,则不会出现后台消息。
回答by brozot
Try to set content_available to true.
尝试将 content_available 设置为 true。
From the fcm documentation :
Note: If you want to send messages consisting of only custom key-values to an iOS device when the app is in the background, set custom key-value pairs in the data key and set content_available to true.
从 fcm 文档:
注意:如果您想在应用程序处于后台时向 iOS 设备发送仅包含自定义键值的消息,请在数据键中设置自定义键值对并将 content_available 设置为 true。
{
registeration_ids : [<id_1>, <id_2>],
content_available: true,
data : {
title : message_title,
body : message_body,
intended_user : message_user
}
}
回答by Shayan C
From what I understand so far, there is no way of solving this issue properly on the ios side. It works perfectly on the android side because the application is awoken in all states (foreground, background & closed).
据我目前的了解,在 ios 方面没有办法正确解决这个问题。它在 android 端完美运行,因为应用程序在所有状态(前台、后台和关闭)下都被唤醒。
You have two kinds of messages you can send:
您可以发送两种消息:
A notification-messagewhich is displayed and handled by the operating system directly.
甲通知消息,将其直接显示和处理由操作系统。
A data-messagewhich is handled by the application.
甲数据消息由所述应用程序处理。
If you add a custom tag, it now becomes a data-message and would have to be handled by the application. You can add a content_available
tag in data-message to let the application know about the message but the problem is that the data-message is only delivered to the application in ios if the application is in the foregrounded (opened) or in the background (minimised). The data-message will not be delivered to the application if the user has "force-closed" the application (even with the background notifications enabled).
如果您添加自定义标记,它现在会变成数据消息并且必须由应用程序处理。您可以content_available
在 data-message 中添加一个标签,让应用程序知道该消息,但问题是如果应用程序处于前台(打开)或后台(最小化),则数据消息仅传递给 ios 中的应用程序)。如果用户“强制关闭”了应用程序(即使启用了后台通知),数据消息将不会传送到应用程序。
Solution is to handle the intended user on the server side and solve the multiple-users to one-device-token problem by maintaining the a one to one device-token to user relationship.
解决方案是在服务器端处理目标用户,通过维护一对一的设备令牌与用户的关系来解决多用户到一个设备令牌的问题。
回答by emilpmp
Poor Documentation from Firebase!
Firebase 的文档很差!
For iOS, Data messages can't be received when app is killed. But this is not mentioned anywhere in their documentation. So I contacted Firebase and this is what they said:
对于iOS,当应用程序被杀死时无法接收数据消息。但这在他们的文档中没有任何地方提到。所以我联系了 Firebase,他们是这样说的:
Though there is a content_available parameter, data messages cannot be received when the app is killed. It can only be received on background and in foreground. If you wish to receive data messages when the app is killed, you need to send it along a display messages.
虽然有 content_available 参数,但是当应用程序被杀死时无法接收数据消息。它只能在后台和前台接收。如果您希望在应用程序被终止时接收数据消息,则需要将其与显示消息一起发送。
So its better to use APNS for ios rather if you ever thought of using same payload for android and Ios in FCM.
因此,如果您曾经想过在 FCM 中为 android 和 Ios 使用相同的有效负载,那么最好将 APNS 用于 ios。
回答by Prcela
I noticed that notification will arrive when app is force-closed in case that notification priority is set to high.
我注意到如果通知优先级设置为高,则当应用程序被强制关闭时通知将到达。
{ "notification": {
"body" : "This week's edition is now available.",
"title": "Portugal vs. Denmark",
"text": "5 to 1",
"content_available": 1
},
"data" : {
"volume" : "3.21.15",
"contents" : "http://www.news-magazine.com/world-week/21659772"
},
"to" : "fqUk65A1kTE:APA91bG5...", // or set topic like "/topics/test"
"priority" : "high"
}
For iOS client apps, normal and high priority are analogous to APNs priority levels 5 and 10.
对于 iOS 客户端应用程序,普通优先级和高优先级类似于 APN 优先级 5 和 10。
From the iOS documentation it is possible that notification with default priority are not delivered.
从 iOS 文档来看,具有默认优先级的通知可能不会被传递。
apns-priority: The priority of the notification. Specify one of the following values:
10–Send the push message immediately. Notifications with this priority must trigger an alert, sound, or badge on the target device. It is an error to use this priority for a push notification that contains only the content-available key.
5—Send the push message at a time that takes into account power considerations for the device. Notifications with this priority might be grouped and delivered in bursts. They are throttled, and in some cases are not delivered. If you omit this header, the APNs server sets the priority to 10.
apns-priority:通知的优先级。指定以下值之一:
10-立即发送推送消息。具有此优先级的通知必须在目标设备上触发警报、声音或徽章。将此优先级用于仅包含内容可用密钥的推送通知是错误的。
5—在考虑到设备电源的时间发送推送消息。具有此优先级的通知可能会被分组并以突发方式传送。它们受到限制,在某些情况下无法交付。如果省略此标头,APNs 服务器会将优先级设置为 10。
Update 1:
更新 1:
The above notification is sent through FCM api and it was received while app was killed. After I tap the notification on device this is what appears in device log after the app has started:
上述通知是通过 FCM api 发送的,它是在应用程序被杀死时收到的。在我点击设备上的通知后,这是应用程序启动后设备日志中显示的内容:
...didReceiveRemoteNotification: [gcm.message_id: 0:1468481012881485%e1d60a46e1d60a46, volume: 3.21.15, aps: {
alert = {
body = "This week\U2019s edition is now available.";
title = "Portugal vs. Denmark";
};
}, contents: http://www.news-magazine.com/world-week/21659772][;
Notice that data part is also contained in received message.
请注意,数据部分也包含在接收到的消息中。
Update 2:
更新 2:
Multiple users on single device or one user with many devices.
单个设备上的多个用户或多个设备上的一个用户。
On your server side you must assure that one unique fcm_id can be assigned only to one user. This means that one device is assigned to one user, so only one user will be notified per device.
在您的服务器端,您必须确保一个唯一的 fcm_id 只能分配给一个用户。这意味着一台设备被分配给一个用户,因此每台设备只会通知一个用户。
Also, one user can have multiple fcm_ids, so it means user can have more devices and be signed in.
此外,一个用户可以有多个 fcm_id,这意味着用户可以拥有更多设备并登录。
When the user_2 log in to same device of user_1, fcm_id must be detached from the user_1 and attached to user_2. Within this way, only currently logged in user will receive the message.
当user_2登录到user_1的同一台设备时,fcm_id必须与user_1分离并附加到user_2上。这样,只有当前登录的用户才会收到消息。
回答by Wendy Chan
The key problem is sending message to specific user group for the latest identity logged in.
关键问题是向特定用户组发送最新登录身份的消息。
Actually you can use topic messaging to solve the problem. Suppose you have 3 user tags/groups A,B and C. When FCM is initialized, register to 1 topic for All users to ensure that you can send a message to all user tags.
其实你可以使用主题消息来解决这个问题。假设您有 3 个用户标签/组 A、B 和 C。当 FCM 初始化时,为所有用户注册 1 个主题,以确保您可以向所有用户标签发送消息。
For specific user tags, subscribe to A if user signed in as A. After the user signed out and signed in as B, check if the user has subscribed to A/C or not. If yes, unsubscribe from A/C and then subscribe to B. This can then avoid handling tags involved in data section.
对于特定的用户标签,如果用户以A身份登录,则订阅A。用户注销并以B身份登录后,检查用户是否订阅了A/C。如果是,取消订阅A/C,然后订阅B。这样可以避免处理数据部分涉及的标签。