如何向特定平台发送通知?

6
我想向Android和iOS发送两个不同的通知。我希望向iOS发送一个通知消息,这样iOS会显示一个漂亮的通知。对于Android,我想发送一条数据消息,这样我就可以在Android和后台处理通知(因为我在后台没有回调并且想自己处理它)。
我查看了文档,但找不到关于发送到特定平台的任何信息。我该怎么做?
另外,欢迎提出其他建议,但请记住,我特别想通过Android上的回调(onMessageReceived)自己处理通知。

我认为你需要在服务器端存储有关设备操作系统类型和Firebase设备令牌的信息。然后,负责发送通知的应用程序应该查找iOS和Android设备,并按照你的要求发送正确的通知。我已经以这种方式完成了它,在我的环境中可以实现类似的功能。 - Patryk Jabłoński
@PatrykJabłoński 这是可以做到的,但这样你就没有使用 Firebase 的强大功能了。我也可以订阅 Android 主题,这会更好一些,但仍然不是我要找的。Firebase 应该拥有所有这些信息,只是我不知道如何使用它。例如,从控制台中,您可以向应用程序的 Android 版本发送特定的消息。我只是在 http api 文档中找不到它,并且我还需要将其发送到特定主题。 - Kevin van Mierlo
你想从一个设备向另一个设备发送推送通知吗?@KevinvanMierlo - Yuyutsu
@Yuyutsu 好的,我在这里问一下应该如何发送请求,以便向特定平台和特定主题发送推送消息。目前我只是发送到一个主题。所以像这样的东西:{ "to": "topics/topic", "notification": { "body": "great match!", "title": "Portugal vs. Denmark" }, "data": { "Nick": "Mario", "Room": "PortugalVSDenmark" } } - Kevin van Mierlo
@PatrykJabłoński 是的,那也是我的担心。我只是不明白为什么我不能在 Android 后台处理通知。这样就可以解决所有问题了。 - Kevin van Mierlo
显示剩余12条评论
2个回答

7
更新: FCM最近添加了一个功能,可以为特定平台提供特定参数的选项,称为平台覆盖

跨平台自定义消息

由 FCM v1 HTTP 协议发送的消息可以包含两种类型的 JSON 键值对:

  • 一组通用键,所有接收到消息的应用实例都将解释这些键。
  • 仅由在指定平台上运行的应用实例解释的平台特定键块。

平台特定块使您可以灵活地为不同平台定制消息,以确保在接收到消息时正确处理它们。在许多场景下,在给定消息中同时使用通用键和平台特定键是有意义的。

何时使用通用键

  • 每当您针对所有平台 - iOS、Android 和网页实例时
  • 当您发送消息到主题时

无论平台如何解释,所有应用实例都会解释的通用键是 message.notification.titlemessage.notification.bodymessage.data

何时使用平台特定键

  • 当您只想将字段发送到特定平台时
  • 为了在通用键之外发送平台特定字段

每当您只想向特定平台发送值时,不要使用通用键;而是使用平台特定的键块。例如,要仅向 iOS 和 Web 发送通知,但不是 Android,则必须使用两个单独的键块,一个用于 iOS,一个用于 Web。

在发送具有特定交付选项的消息时,请使用平台特定键进行设置。如果您希望每个平台指定不同的值,则可以指定不同的值;但即使您希望在平台上设置基本相同的值,也必须使用平台特定的键。这是因为每个平台可能会略微不同地解释该值 - 例如,在 Android 上将 TTL 设置为以秒为单位的过期时间,而在 iOS 上将其设置为过期日期

示例:带有平台特定交付选项的通知消息

以下 v1 发送请求将一个通用的通知标题和内容发送到所有平台,但还发送了一些平台特定覆盖。具体来说,该请求:

  • 为 Android 和 Web 平台设置长时间到期时间,同时将 APNs(iOS)消息优先级设置为低。
  • 设置适当的键以定义在 Android 和 iOS 上点击通知的结果 - 分别为 click_actioncategory
{
  "message":{
     "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
     "notification":{
       "title":"Match update",
       "body":"Arsenal goal in added time, score is now 3-0"
     },
     "android":{
       "ttl":"86400s",
       "notification"{
         "click_action":"OPEN_ACTIVITY_1"
       }
     },
     "apns": {
       "headers": {
         "apns-priority": "5",
       },
       "payload": {
         "aps": {
           "category": "NEW_MESSAGE_CATEGORY"
         }
       }
     },
     "webpush":{
       "headers":{
         "TTL":"86400"
       }
     }
   }
 }

请参阅HTTP v1参考文档,以获取有关消息正文中平台特定块中可用键的完整详细信息。有关构建包含消息正文的发送请求的更多信息,请参见构建发送请求
我记得之前回答过类似的问题,但现在找不到了。目前还没有选项可以指定发送消息的平台。最简单的方法是使用主题消息。每次生成令牌时,您可以从客户端应用程序确定平台类型,并将其订阅到相应的主题(例如topics/(Android/iOS)_<Your App Name>),然后根据需要发送消息。如果您正在使用Firebase DB,则最好跟踪来自服务器的注册令牌,您可以将它们放在一个节点中。
/pushTokens
  /android
    /{userId} : string
  /ios
    /{userid}: string

这将让您能够从后端检查并根据需要调整有效载荷,以便在发送单个消息时使用。


1
谢谢!很遗憾,在Android上没有一种好的方式可以在前台和后台使用Firebase并保持iOS相同。但是,这可能是目前最好的解决方案。 - Kevin van Mierlo
@KevinvanMierlo 看看我的更新。我自己没有尝试过平台覆盖,但它似乎是你最初寻找的东西。 - AL.
1
谢谢!我会研究一下的。它看起来确实是我想要的东西。 - Kevin van Mierlo
平台覆盖似乎是正确的方向。例如,要仅发送到iOS设备:不要包括常见的顶级“notifications”键,并将这些值移动到“apns”部分,遵循苹果的“payload”字典结构。 - Tudor

1
I was facing same issue with Android Development. We used Laravel on backend side. On backend side, developer has to maintain different scenario for both platforms.
In Android:
FCM::sendTo($tokens, $option, null, $data);

在这里,将null作为通知构建器传递。当您在通知中传递null并创建databuilder($data)时,您可以在应用程序后台接收到消息的onMessageReceived方法。 对于iOS:
FCM::sendTo($tokens, $option, $notification, $data);

在这里,您可以在$notification中传递通知构建器。因此,iOS设备也可以收到通知。

是的,但问题在于服务器必须知道哪个设备是Android,哪个设备是iOS。除了AL提供的答案外,Firebase没有区分iOS和Android的方法。 - Kevin van Mierlo
当用户登录时,您必须拥有关于服务器操作系统的信息。 - SANAT
1
是的,但这是一个问题,因为你再也不能使用Firebase提供的主题或其他内容了。我们在另一个项目中使用这个解决方案,因为它只有个别推送通知。但是这个应用程序需要主题功能。 - Kevin van Mierlo

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