

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 Amazon SNS 中使用 Google Firebase Cloud Messaging v1 有效载荷
FCM v1 API 有效载荷

Amazon SNS 支持使用 FCM HTTP v1 API 向 Android、iOS 和 Webpush 目标发送通知。本主题提供了使用 CLI 或 Amazon SNS API 发布移动推送通知时的有效载荷结构示例。

发送 FCM 通知时，您可以在有效载荷中包含以下消息类型：
+ **数据消息** - 数据消息由您的客户端应用程序处理，并包含自定义键值对。在构造数据消息时，必须包含以 JSON 对象作为值的 `data` 键，然后输入您的自定义键值对。
+ **通知消息**或**显示消息** - 通知消息包含由 FCM SDK 处理的一组预定义键。这些键因您要传送到的设备类型而异。有关特定于平台的通知键的更多信息，请参阅以下内容：
  + [Android 通知键](https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages)
  + [APNS 通知键](https://developer.apple.com/documentation/usernotifications/generating-a-remote-notification)
  + [Webpush 通知键](https://developer.mozilla.org/en-US/docs/Web/API/Notification)

有关 FCM 消息类型的更多信息，请参阅 Google 的 *Firebase* 文档中的[消息类型](https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages)。

## 使用 FCM v1 有效载荷结构发送消息


如果您是首次创建 FCM 应用程序，或者希望利用 FCM v1 的功能，则可以选择发送 FCM v1 格式的有效载荷。为此，必须包含顶层键 `fcmV1Message`。*有关构建 FCM v1 有效负载的更多信息，请参阅 Google 的 Firebase 文档[中的从旧版 FCM 迁移 APIs 到 HTTP v1](https://firebase.google.com/docs/cloud-messaging/migrate-v1) 和[跨平台自定义消息](https://firebase.google.com/docs/cloud-messaging/concept-options#customizing-a-message-across-platforms)。*

**发送到 Amazon SNS 的 FCM v1 有效载荷示例：**

**注意**  
使用 Amazon SNS 发布通知时，以下示例中使用的 `GCM` 键值必须编码为字符串。

```
{
  "GCM": "{ 
    \"fcmV1Message\": { 
      \"validate_only\": false,
      \"message\": {
        \"notification\": {
          \"title\": \"string\",
          \"body\": \"string\"
        },
        \"data\": {
          \"dataGen\": \"priority message\"
        },
        \"android\": {
          \"priority\": \"high\",
          \"notification\": {
            \"body_loc_args\": [\"string\"],
            \"title_loc_args\": [\"string\"],
            \"sound\": \"string\",
            \"title_loc_key\": \"string\",
            \"title\": \"string\",
            \"body\": \"string\",
            \"click_action\": \"clicky_clacky\",
            \"body_loc_key\": \"string\"
          },
          \"data\": {
            \"dataAndroid\": \"priority message\"
          },
          \"ttl\": \"10023.32s\"
        },
        \"apns\": {
          \"payload\": {
            \"aps\": {
              \"alert\": {
                \"subtitle\": \"string\",
                \"title-loc-args\": [\"string\"],
                \"title-loc-key\": \"string\",
                \"loc-args\": [\"string\"],
                \"loc-key\": \"string\",
                \"title\": \"string\",
                \"body\": \"string\"
              },
              \"category\": \"Click\",
              \"content-available\": 0,
              \"sound\": \"string\",
              \"badge\": 5
            }
          }
        },
        \"webpush\": {
          \"notification\": {
            \"badge\": \"5\",
            \"title\": \"string\",
            \"body\": \"string\"
          },
          \"data\": {
            \"dataWeb\": \"priority message\"
          }
        }
      }
    }
  }"
}
```

发送 JSON 有效载荷时，请务必在请求中包含该 `message-structure` 属性，并将其设置为 `json`。

**CLI 示例：**

```
aws sns publish --topic $TOPIC_ARN --message '{"GCM": "{\"fcmV1Message\": {\"message\":{\"notification\":{\"title\":\"string\",\"body\":\"string\"},\"android\":{\"priority\":\"high\",\"notification\":{\"title\":\"string\",\"body\":\"string\"},\"data\":{\"customAndroidDataKey\":\"custom key value\"},\"ttl\":\"0s\"},\"apns\":{\"payload\":{\"aps\":{\"alert\":{\"title\":\"string\", \"body\":\"string\"},\"content-available\":1,\"badge\":5}}},\"webpush\":{\"notification\":{\"badge\":\"URL\",\"body\":\"Test\"},\"data\":{\"customWebpushDataKey\":\"priority message\"}},\"data\":{\"customGeneralDataKey\":\"priority message\"}}}}", "default": "{\"notification\": {\"title\": \"test\"}"}' --region $REGION --message-structure json
```

*有关发送 FCM v1 格式的有效载荷的更多信息，请参阅 Google 的 Firebase* 文档中的以下内容：
+ [从旧版 FCM 迁移 APIs 到 HTTP v1](https://firebase.google.com/docs/cloud-messaging/migrate-v1)
+ [关于 FCM 消息](https://firebase.google.com/docs/cloud-messaging/concept-options#customizing_a_message_across_platforms)
+ [REST 资源：projects.messages](https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages)

## 使用旧版有效载荷结构向 FCM v1 API 发送消息


迁移到 FCM v1 时，您无需更改用于旧版凭证的有效载荷结构。Amazon SNS 会将您的有效载荷转换为新的 FCM v1 有效载荷结构，然后发送给 Google。

输入消息有效载荷格式：

```
{
  "GCM": "{\"notification\": {\"title\": \"string\", \"body\": \"string\", \"android_channel_id\": \"string\", \"body_loc_args\": [\"string\"], \"body_loc_key\": \"string\", \"click_action\": \"string\", \"color\": \"string\", \"icon\": \"string\", \"sound\": \"string\", \"tag\": \"string\", \"title_loc_args\": [\"string\"], \"title_loc_key\": \"string\"}, \"data\": {\"message\": \"priority message\"}}"
}
```

发送给 Google 的消息：

```
{
  "message": {
    "token": "***",
    "notification": {
      "title": "string",
      "body": "string"
    },
    "android": {
      "priority": "high",
      "notification": {
        "body_loc_args": [
          "string"
        ],
        "title_loc_args": [
          "string"
        ],
        "color": "string",
        "sound": "string",
        "icon": "string",
        "tag": "string",
        "title_loc_key": "string",
        "title": "string",
        "body": "string",
        "click_action": "string",
        "channel_id": "string",
        "body_loc_key": "string"
      },
      "data": {
        "message": "priority message"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "alert": {
            "title-loc-args": [
              "string"
            ],
            "title-loc-key": "string",
            "loc-args": [
              "string"
            ],
            "loc-key": "string",
            "title": "string",
            "body": "string"
          },
          "category": "string",
          "sound": "string"
        }
      }
    },
    "webpush": {
      "notification": {
        "icon": "string",
        "tag": "string",
        "body": "string",
        "title": "string"
      },
      "data": {
        "message": "priority message"
      }
    },
    "data": {
      "message": "priority message"
    }
  }
}
```

**潜在风险**
+ 旧版到 v1 的映射不支持 Apple 推送通知服务（APNS）`headers` 或 `fcm_options` 键。如果希望使用这些字段，请发送 FCM v1 有效载荷。
+ 在某些情况下，FCM v1 要求消息标头才能向您的 APNs 设备发送静默通知。如果您当前正在向 APNs 设备发送静默通知，则它们不适用于传统方法。相反，我们建议使用 FCM v1 有效载荷以避免意外问题。要查找 APNs 标题列表及其用途，请参阅《*Apple 开发者指南》 APNs*中的 “[与之通信](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html)”。
+ 如果您在发送通知时使用的是 `TTL` Amazon SNS 属性，则它只会在 `android` 字段中进行更新。如果您想设置 `TTL` APNS 属性，请使用 FCM v1 有效载荷。
+ `android`、`apns` 和 `webpush` 键将被映射并用所提供的所有相关键填充。例如，如果您提供 `title`（这是所有三个平台之间共享的键），FCM v1 映射将使用您提供的标题填充所有三个平台。
+ 一些平台间的共享键需要不同的值类型。例如，传递给 `apns` 的 `badge` 键需要一个整数值，而传递给 `webpush` 的 `badge` 键需要一个字符串值。如果您提供了 `badge` 键，FCM v1 映射将仅填充您为其提供了有效值的键。

## FCM 传输失败事件


下表提供了 Amazon SNS 失败类型，该类型与从 Google 收到的 FCM v1 通知请求的错误/状态代码相对应。当您为应用程序设置[交付状态日志 CloudWatch ](topics-attrib.md)时，可以查看从 FCM v1 API 收到的所有观察到的错误代码。


| FCM 代码 error/status  | Amazon SNS 失败类型 | 失败消息 | 原因和缓解措施 | 
| --- | --- | --- | --- | 
|  `UNREGISTERED`  |  `InvalidPlatformToken`  |  与端点关联的平台令牌无效。  |  连接到您的端点的设备令牌已过时或无效。Amazon SNS 禁用了您的端点。将 Amazon SNS 端点更新为最新的设备令牌。  | 
|  `INVALID_ARGUMENT`  |  `InvalidNotification`  |  通知正文无效。  |  设备令牌或消息有效载荷可能无效。验证您的消息有效载荷是否有效。如果消息有效载荷有效，请将 Amazon SNS 端点更新为最新的设备令牌。  | 
|  `SENDER_ID_MISMATCH`  |  `InvalidPlatformToken`  |  与端点关联的平台令牌无效。  |  与设备令牌关联的平台应用程序无权向设备令牌发送消息。确认您在 Amazon SNS 平台应用程序中使用了正确的 FCM 凭证。  | 
|  `UNAVAILABLE`  |  `DependencyUnavailable`  |  依赖关系不可用。  |  FCM 无法实时处理请求。Amazon SNS 执行的所有重试都失败。您可以将这些消息存储在死信队列（DLQ）中，以后再重新发送它们。  | 
|  `INTERNAL`  |  `UnexpectedFailure`  |  意外失败；请联系 Amazon。失败短语 [内部错误]。  |  FCM 服务器在处理您的请求时遇到错误。Amazon SNS 执行的所有重试都失败。您可以将这些消息存储在死信队列（DLQ）中，以后再重新发送它们。  | 
|  `THIRD_PARTY_AUTH_ERROR`  |  `InvalidCredentials`  |  平台应用程序凭证无效。  |  无法发送针对 iOS 设备或 Webpush 设备的消息。验证您的开发和生产凭证是否有效。  | 
|  `QUOTA_EXCEEDED`  |  `Throttled`  |  请求受 [gcm] 限制。  |  已超过消息速率配额、设备消息速率配额或主题消息速率配额。有关如何解决此问题的信息，请参阅 [ErrorCode](https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode)Google 的 *Firebase* 文档中的。  | 
|  `PERMISSION_DENIED`  |  `InvalidNotification`  |  通知正文无效。  |  如果出现 `PERMISSION_DENIED` 异常，则调用方（您的 FCM 应用程序）无权在有效载荷中执行指定操作。导航到您的 FCM 控制台，并验证您的凭证是否启用了所需的 API 操作。  | 