本文主要记录APNs、FCM消息推送的格式以及后端服务集成消息推送时遇到的一些问题,使用的环境为Node.js + AWS SNS。

AWS SNS是一个AWS的消息管理服务,本文中我们主要通过其创建多平台的消息推送。我们可以通过SNS对多个平台发送消息,如APNs(iOS)、FCM(Android)等。文中的消息推送可以简单地通过以下Node.js代码实现(Typescript)。

import { SNS } from 'aws-sdk';

const sns = new SNS({
  accessKeyId: '***',
  secretAccessKey: '***',
  region: '***',
});

const params = {
  // 发送消息提醒到topic则需要填写此项,本文中主要是发送到topic
  TopicArn: '',

  // 发送消息提醒到指定终端则填写此项而非TopicArn
  // TargetArn: '',

  // 消息推送内容的类型,值为json
  MessageStructure: 'json'

  // 消息提醒的内容
  Message: JSON.stringify({
    // 若发送至topic,必须包含default,其代表发送至未被指定的平台的内容
    default: '默认消息',
    // 为指定平台发送数据时,必须为JSON键值对字符串
    APNS: JSON.stringify({
      aps: {
        alert: {
          title: '你好,iOS',
          body: '这是提醒内容',
        },
      },
      data: {
        customId: '123',
      }
    }),
    // 即FCM
    GCM: JSON.stringify({
      notification: {
        title: '你好,Android',
        body: '这是提醒内容',
      },
      data: {
        customId: '123',
      }
    }),
  }),
}

sns.publish(params);

在消息发送后,订阅了该topic的生产环境下的iOS终端将收到标题为'你好,iOS'的消息提醒,Android端将收到'你好,Android'的消息提醒,其它终端(例如iOS开发环境或浏览器)将收到'默认消息'

APNs数据格式(iOS)

APNs(Apple Push Notification service)是为苹果终端设备推送消息提醒的服务。首先,我们先看一个APNs推送的内容示例:

{
  "aps": {
    "alert": {
      "title": "",
      "body": "",
    }
  },
  // other custom data...
  "data": {
    "customId": ""
  }
}

其中,aps表示一些苹果定义的推送设置内容,关于其值可参考aps部分键值对说明

aps外,我们还可以加入一些自定义的内容,如示例中的customId

aps字段说明

名称 类型 说明
alert 字典或字符串 推送横幅展示的内容,为字符串时直接展示该字符串的值,为字典时值请参考下表
badge 数值 app标记(badge)显示的数字,为0则不显示标记
sound 字符串或字典 接受推送时的声音提醒,默认为default,关于更多推送声音可参考UNNotificationSound
thread-id 字符串 用于不同类型消息提醒的分组
category 字符串 消息提醒的类型,可以参考Declaring Your Actionable Notification Types
content-available 数值 其值为1且不包含alertbadge以及sound时表示该消息提醒为后台提醒
mutable-content 数值 其值为1时该消息推送需要先经过app端处理,可参考Modifying Content in Newly Delivered Notifications
target-content-id 字符串 打开窗口的标识符

关于更多的aps部分说明可参考Payload Key Reference Table 1

alert部分常用字段说明

名称 类型 说明
title 字符串 消息提醒的主标题
subtitle 字符串 消息提醒的副标题,用于表示解释推送目的的额外信息
body 字符串 消息提醒的主要内容
launch-image 字符串 表示用户通过点击消息提醒打开app时展示的图片

另外,alert部分还定义了loc-keyloc-args等与本地化相关的字段,如需使用可参考文档。关于更多的alert部分说明可参考Payload Key Reference Table 2

FCM数据格式

FCM(Firebase Cloud Messaging)是一个跨平台的消息解决方案,在2018年起Google使用FCM替代GCM(Google Cloud Messaging)。同样,我们先看一下FCM的推送内容示例:

{
  "notification": {
    "title": "",
    "body": "",
  },
  "data": {
    "customId": ""
    //
  }
}

其中,notification部分为预先定义的系统使用字段,其包含的字段可参考notification部分常用字段data部分为用户自定义字段,如示例中的{"customId": ""}

notification部分常用字段

名称 类型 说明
title 字符串 消息提醒标题
body 字符串 消息提醒主要内容
icon 字符串 消息提醒的图标,默认为在manifest中定义的app图标
sound 字符串 消息提醒播放的声音,默认为default
notification_count 数值 设置消息提醒的标示数字
visibility 布尔值 是否展示消息提醒
image 字符串 消息提醒展示的图片

关于更多的FCM字段,可参考AndroidNotification - Firebase

无法获取数据的问题

正确区分开发环境与生产环境

有些平台的推送需要区分不同的环境,例如iOS的推送APNs,需要区分APNS以及APNS_SANDBOX。在使用AWS SNS创建Topic消息时,若使用了错误的环境,可能导致终端接收到的数据为default中的信息。例如在我们上面的测试代码中发送消息至开发环境,终端接收到的数据可能为:

{
  "aps": {
    "alert": "默认消息"
  }
}

使用SNS需将payload转为字符串

使用SNS创建消息推送时,必须将各payload数据先转为字符串的形式,否则可能无法收到正确的推送内容,如示例代码中的APNS: JSON.stringify({})

参考资料