FCM与IOS数据通知

21

我正在使用FCM(Firebase云消息传递)向iOS应用发送“自定义”数据通知。据我所知,当您希望FCM代表您的应用程序处理通知时,我们使用通知消息来处理显示通知。当您只想在应用中处理消息时,我们使用数据消息。这是按设计来的。

我面临的问题是,设备/实例ID令牌是安装的应用程序而不是登录应用程序的用户唯一的。因此,为了解决这个问题,我将预期的用户标记发送到数据中,以使它成为数据消息。由于应用程序处理数据通知,因此当应用程序打开并且只有在通知被显示时才会触发didReceiveRemoteNotification()回调。

我的问题是,我是否可以发送自定义数据通知消息,并使它立即出现,即使应用程序已关闭。

这是我发送到FCM的有效载荷:

{
    registeration_ids : [<id_1>, <id_2>],
    data : {
        title   : message_title,
        body    : message_body, 
        intended_user : message_user
    }
}
在Android中,即使应用程序处于后台,也会调用FirebaseMessagingService.onMessageReceived(),但在iOS中,只有在应用程序启动时才会调用didReceiveRemoteNotification(),因此如果您发送数据消息,则不会显示后台消息。

你是从API还是Firebase控制台发送消息?所有来自Firebase控制台的消息都是通知消息,即使带有自定义数据。如果您是从API发送,请包含您提出的请求,这将澄清您的意图。 - Arthur Thompson
1
我正在通过 API 发送消息。请查看问题的更新版本以获取有效载荷数据。 - Shayan C
1
在iOS上,当您的应用程序处于后台时,将无法接收到FCM数据消息。这是因为当您的应用程序处于后台时,您必须(应该)断开与FCM的连接。您应该尝试发送通知消息,该消息通过APNs传递,设置content_available字段,以便您的应用程序能够处理后台回调。 - Arthur Thompson
5个回答

26

Firebase文档缺乏细节!

iOS设备在应用程序关闭时无法接收数据消息。但是这一点在Firebase的文档中并没有提到。因此我联系了Firebase,以下是他们的回答:

虽然有一个content_available参数,但是当应用程序关闭时,数据消息无法被接收。它只能在后台和前台接收。如果您希望在应用程序关闭时接收数据消息,则需要将其与显示消息一起发送。

因此,如果您想在FCM中使用相同的负载来适用于Android和iOS系统,最好使用APNS推送服务进行iOS开发。


是的,基本上就是这样。这是我联系 Firebase 后得到的回复。我不确定他们是否已经更新了 SDK 以包含这些更改。请参考他们最新的文档获取更多信息。 - emilpmp
你用过APNS吗? - Shubham1164
我们能否像在Android中那样使用APNS唤醒已经被杀死的IOS应用程序? - Shubham1164
APNS被推荐用于iOS通知。即使应用程序被终止,也会显示通知。 - emilpmp
我正在使用React Native。如何在IOS中实现它?有什么指导吗? - Shubham1164
显示剩余2条评论

25

据我所了解,目前在iOS端没有有效的方法可以妥善地解决这个问题。在Android端,应用程序处于所有状态(前台、后台和关闭)下都能正常工作。

您有两种消息可以发送:

通知消息会直接由操作系统显示和处理。

数据消息由应用程序处理。

如果您添加了自定义标签,则它现在变成了数据消息,并且必须由应用程序处理。您可以在数据消息中添加content_available标签,让应用程序知道有新消息到达,但是问题在于,如果用户已经将应用程序“强制关闭”(即使启用了后台通知),则数据消息仅在应用程序在前台(打开)或后台(最小化)时才会传递给应用程序。

解决方案是在服务器端处理要发送给的用户,并通过维护一对一的设备令牌与用户关系来解决多个用户对一个设备令牌的问题。


1
那么你的意思是,如果我想处理从 FCM 发送到设备的数据以生成消息,我别无选择,只能等待应用程序被打开? - Dylanthepiguy
只有当应用程序没有运行时才执行。 - Kylea
@Dylanthepigguy 你也可以发送一个通知,它会显示在系统托盘中,并且可以包含一个链接来激活应用程序。 - Kato
还在苹果的文档中提到了这里 - Kato

18

尝试将 content_available 设置为 true。

来自 FCM 文档:

注意:如果您想在 iOS 设备后台发送仅由自定义键值组成的消息,请在 data 键中设置自定义键值对,并将 content_available 设置为 true。

{
    registeration_ids : [<id_1>, <id_2>],
    content_available: true,

    data : {
        title   : message_title,
        body    : message_body, 
        intended_user : message_user
    }
}

3
感谢您提供的解决方案,但在应用程序方面没有解决这个问题的方法。如果应用程序处于后台或前台,content_available 才能起作用。如果用户通过“强制关闭”应用程序,则数据消息无法传递到应用程序中(只有 iOS 受此影响,在 Android 上运行良好)。解决方案是使用通知消息,其中消息的显示由操作系统处理,而不是应用程序处理。我们通过在服务器端维护设备令牌与用户之间的一对一映射来解决所需的用户问题。 - Shayan C

17

我注意到,如果通知优先级设置为高,则在应用程序被强制关闭时会收到通知。

{  "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"
}

对于iOS客户端应用程序,普通优先级和高优先级类似于APNs优先级级别5和10。

根据iOS文档,具有默认优先级的通知可能无法传送。

apns-priority:通知的优先级。指定以下值之一:

10-立即发送推送消息。具有此优先级的通知必须在目标设备上触发警报、声音或徽章。对于仅包含content-available密钥的推送通知使用此优先级是错误的。

5-在考虑设备功耗的时间发送推送消息。具有此优先级的通知可能会分组并以突发方式传送。它们受到限制,并且在某些情况下不会传递。如果省略此标题,则APNs服务器将优先级设置为10。

更新1:

以上通知通过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][;

请注意,接收到的消息中也包含数据部分。

更新2:

单个设备上的多个用户或一个用户拥有多个设备。

在您的服务器端,您必须确保一个唯一的fcm_id只能被分配给一个用户。这意味着一个设备只分配给一个用户,因此每个设备只会通知一个用户。

此外,一个用户可以有多个fcm_ids,这意味着用户可以拥有更多的设备并且已登录。

当用户2登录到用户1的同一设备时,fcm_id必须从用户1中分离并附加到用户2中。通过这种方式,只有当前已登录的用户将接收消息。


我已将优先级设置为高。问题是,如果应用程序从后台中移除,则数据部分将无法被处理。 - Shayan C
这是正确的,但我认为你没有理解我试图解决的问题。如果在数据中添加了预期用户标签,那么当应用程序关闭时就不会立即通知。必须由用户打开应用程序以读取预期的用户标签,然后显示通知。唯一能够在多个用户登录同一设备时即时传递通知的方法是在服务器端保留当前用户到设备令牌的记录。 - Shayan C
1
@yoyo,如果服务器端的“priority”:“high”,当应用程序被杀死时,您是否收到了消息?我只是好奇想知道,因为我们在iOS上遇到了同样的问题。 - Subho
1
在浪费了几个小时试图理解为什么iOS设备上的通知会随机发送后,设置"priority" : "high"最终救了我。谢谢 :) - Hadi tavakoli
如果iOS设备应用程序已被关闭,则无法向iOS发送数据消息。在iOS情况下,“priority”:“high”无法解决数据消息问题。根据Firebase的规定,只有在iOS应用程序关闭时才能发送通知消息。@MyFlashLab - Subho
显示剩余5条评论

3
关键问题在于向特定用户组发送最新登录的身份的消息。
实际上,您可以使用主题消息来解决这个问题。假设您有3个用户标签/组A、B和C。当FCM初始化时,注册所有用户的1个主题,以确保您可以向所有用户标签发送消息。
对于特定的用户标签,如果用户以A身份登录,则订阅A。当用户退出并以B身份登录时,请检查用户是否已经订阅了A/C。如果是,则取消A/C的订阅,然后订阅B。这样就可以避免处理涉及数据部分的标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接