【问题标题】:IOS data notifications with FCM带有 FCM 的 IOS 数据通知
【发布时间】:2016-11-05 02:14:03
【问题描述】:

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

我面临的问题是 Device/InstandID 令牌对于已安装的应用程序是唯一的,而不是登录应用程序的用户。所以为了解决这个问题,我在数据中发送预期的用户标签,使其成为数据消息。由于应用程序处理数据通知,所以 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 发送,您是否可以包含您提出的请求,它将清除您正在尝试的内容。
  • 我正在通过 API 发送消息。请查看有效负载数据问题的更新版本。
  • 当您的应用程序在 iOS 上处于后台时,将不会收到 FCM 数据消息。这是因为当您的应用程序在后台时,您必须(应该)断开与 FCM 的连接。您应该尝试发送一条通知消息,该消息通过 APNs,该 APNs 也将在后台工作,并设置 content_available 字段,以便您的应用能够在后台处理回调。

标签: ios iphone firebase notifications firebase-cloud-messaging


【解决方案1】:

Firebase 的文档很差!

对于 iOS,应用被终止时无法接收数据消息。但这在他们的文档中没有提到。所以我联系了 Firebase,他们是这样说的:

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

因此,如果您曾想过在 FCM 中为 android 和 Ios 使用相同的有效负载,那么最好为 ios 使用 APNS。

【讨论】:

  • 你是认真的吗?
  • 是的。这是我联系他们时 Firebase 的回复。我不确定他们是否更新了 sdk 以包含这些更改。请参阅他们的最新文档以获取更多信息。
  • 你用过APNS吗?
  • 我们可以像使用 Android 一样使用 APNS 唤醒被杀死的 IOS 应用吗>
  • 建议将APNS用于ios通知。是的,即使应用程序被杀死,它也会显示通知
【解决方案2】:

关键问题是向特定用户组发送消息以获取最新登录的身份。

其实你可以使用主题消息来解决问题。假设您有 3 个用户标签/组 A、B 和 C。当 FCM 初始化时,为所有用户注册 1 个主题,以确保您可以向所有用户标签发送消息。

对于特定的用户标签,如果用户以A登录,则订阅A。用户注销并以B登录后,检查用户是否订阅了A/C。如果是,则取消订阅A/C,然后订阅B。这样可以避免处理数据部分涉及的标签。

【讨论】:

    【解决方案3】:

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

    {  "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 客户端应用,正常和高优先级类似于 APN 的优先级 5 和 10。

    从 iOS 文档来看,默认优先级的通知可能不会被传递。

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

    10——立即发送推送消息。具有此优先级的通知 必须在目标设备上触发警报、声音或标记。它是一个 将此优先级用于仅包含的推送通知的错误 内容可用密钥。

    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_id,这意味着用户可以拥有更多设备并登录。

    当 user_2 登录到 user_1 的同一设备时,fcm_id 必须与 user_1 分离并附加到 user_2。这样,只有当前登录的用户才能收到消息。

    【讨论】:

    • 我已将优先级设置为高。问题是如果从后台删除应用程序,数据部分将不会被处理。
    • 这是正确的,但我认为您不明白我要解决的问题。如果我在数据中添加预期的用户标签,这意味着如果应用程序关闭,则不会立即通知。它必须由用户打开以读取预期的用户标签,然后显示通知。在多个用户登录同一设备的情况下,即时发送通知的唯一方法是在服务器端记录当前用户到设备令牌。
    • 显示的通知不包含预期的用户标签。首先显示通知,然后在单击时将预期的用户数据发送到应用程序。使用您的方法,以前登录设备的用户将与当前用户共享他们的消息。如果当前登录的用户是预期用户,我只想显示通知,同时立即发送消息。这样做的唯一方法是将 1 个用户映射到 1 个设备令牌并在服务器端使旧关系失效。
    • @yoyo 如果服务器端的“优先级”:“高”,您是否收到消息(当应用程序被杀死时)?我只是想知道,因为我们在 ios 上面临同样的问题
    • 在浪费了几个小时试图理解为什么 iOS 设备上的通知是随机发送的之后,设置"priority" : "high" 终于救了我。谢谢:)
    【解决方案4】:

    据我目前了解,没有办法在 ios 端正确解决这个问题。它在 android 端完美运行,因为应用程序在所有状态(前景、背景和关闭)下都被唤醒。

    您可以发送两种消息:

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

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

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

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

    【讨论】:

    • 那么你的意思是,如果我想在设备上处理FCM发送的数据以生成消息,我只能等待应用程序打开?跨度>
    • @Dylanthepiguy 仅当应用未运行时。
    • @Dylanthepigguy 您还可以发送通知,该通知会显示在系统托盘中,并且可以包含激活应用程序的链接。
    • Apple 的文档中也提到过 here
    【解决方案5】:

    尝试将 content_available 设置为 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
        }
    }
    

    【讨论】:

    • 感谢您的解决方案,但无法在应用程序端解决此问题。 content_available 仅在应用程序位于后台或前台时才有效。如果应用程序被用户“强制关闭”,则数据消息无法传递到应用程序(只有 ios 受此影响,它在 android 上运行良好)。解决方案是使用通知消息,其中消息的显示由操作系统而不是应用程序处理。我们通过在服务器端维护设备令牌到用户的一对一映射来整理预期的用户内容。
    猜你喜欢
    • 1970-01-01
    • 2017-07-30
    • 1970-01-01
    • 2018-01-28
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多