

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

# 使用 Amazon SNS 发送移动推送通知
<a name="sns-mobile-application-as-subscriber"></a>

您可以使用 Amazon SNS 将推送通知消息直接发送至移动设备上的应用程序。发送到移动端点的推送通知消息可在移动应用程序中显示为消息提醒、徽章更新或声音警报。

![\[Amazon SNS 移动推送通知概述\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/sns-mobile-push-notifications.png)


**Topics**
+ [Amazon SNS 用户通知的工作原理](#sns-how-user-notifications-work)
+ [使用 Amazon SNS 设置推送通知](#sns-user-notifications-process-overview)
+ [在 Amazon SNS 中设置移动应用程序](mobile-push-send.md)
+ [使用 Amazon SNS 发送移动推送通知](mobile-push-notifications.md)
+ [Amazon SNS 移动应用程序属性](sns-msg-status.md)
+ [移动应用程序的 Amazon SNS 应用程序事件通知](application-event-notifications.md)
+ [移动推送 API 操作](mobile-push-api.md)
+ [Amazon SNS 移动推送 API 常见错误](mobile-push-api-error.md)
+ [使用移动推送通知的 Amazon SNS 生存时间消息属性](sns-ttl.md)
+ [Amazon SNS 移动应用程序支持的区域](sns-mobile-push-supported-regions.md)
+ [管理 Amazon SNS 移动推送通知的最佳实践](mobile-push-notifications-best-practices.md)

## Amazon SNS 用户通知的工作原理
<a name="sns-how-user-notifications-work"></a>

使用以下受支持的推送通知服务之一将推送通知消息发送到移动设备和桌面：
+ Amazon Device Messaging（ADM）
+ 适用于 iOS 和 Mac OS X 的 Apple 推送通知服务 (APNs)
+ 百度云推送（百度）
+ Firebase Cloud Messaging (FCM)
+ 适用于 Windows Phone 的 Microsoft 推送通知服务 (MPNS)
+ Windows 推送通知服务（WNS）

推送通知服务（例如 APNs 和 FCM）与注册使用其服务的每个应用程序和关联的移动设备保持连接。在应用程序和移动设备注册时，推送通知服务会返回设备令牌。Amazon SNS 使用该设备令牌创建它能够将直接推送通知消息发送到的移动终端节点。为使 Amazon SNS 与不同推送通知服务通信，您需要将推送通知服务凭证提交给用于代表您的 Amazon SNS。有关更多信息，请参阅 [使用 Amazon SNS 设置推送通知](#sns-user-notifications-process-overview)。

 除了发送直接推送通知消息，还可以使用 Amazon SNS 将消息发送到订阅某个主题的移动终端节点。其概念与订阅其他终端节点类型（如 Amazon SQS、HTTP/S、电子邮件和 SMS）相同，如 [什么是 Amazon SNS？](welcome.md) 中所述。不同之处在于 Amazon SNS 使用推送通知服务通信，使订阅的移动终端节点接收发送给相应主题的推送通知消息。

## 使用 Amazon SNS 设置推送通知
<a name="sns-user-notifications-process-overview"></a>

1. 为要支持的移动平台[获取凭证和设备令牌](sns-prerequisites-for-mobile-push-notifications.md)。

1. 通过 Amazon SNS，使用凭证创建平台应用程序对象 (`PlatformApplicationArn`)。有关更多信息，请参阅 [创建 Amazon SNS 平台应用程序](mobile-push-send-register.md)。

1. 使用返回的凭证从推送通知服务请求您的移动应用程序和设备的设备令牌。收到的令牌表示您的移动应用程序和设备。

1. 通过 Amazon SNS，使用设备令牌和 `PlatformApplicationArn` 创建平台终端节点对象 (`EndpointArn`)。有关更多信息，请参阅 [为移动通知设置 Amazon SNS 平台端点](mobile-platform-endpoint.md)。

1. 使用 `EndpointArn` [向移动设备上的应用发布消息](mobile-push-send.md)。有关更多信息，请参阅 [直接 Amazon SNS 移动设备消息传递](mobile-push-notifications.md#mobile-push-send-directmobile) 和 Amazon Simple Notification Service API 参考 中的[发布](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html) API。

# 在 Amazon SNS 中设置移动应用程序
<a name="mobile-push-send"></a>

该主题介绍如何使用 [Amazon SNS 用户通知的先决条件](sns-prerequisites-for-mobile-push-notifications.md)中描述的信息在 AWS 管理控制台中设置移动应用程序。

# Amazon SNS 用户通知的先决条件
<a name="sns-prerequisites-for-mobile-push-notifications"></a>

要开始使用 Amazon SNS 移动推送通知，您需要：
+ 用于连接支持的推送通知服务之一的一组凭证：ADM、Baidu、FCM APNs、MPNS 或 WNS。
+ 移动应用程序和设备的设备令牌或注册 ID。
+ 配置 Amazon SNS 以将推送通知消息发送到移动终端节点。
+ 注册并配置移动应用程序来使用支持的推送通知服务之一。

使用推送通知服务注册您的应用程序需要几个步骤。Amazon SNS 需要您提供给推送通知服务的一些信息才能将直接推送通知消息发送到移动终端节点。通常而言，您需要连接推送通知服务所需的凭证、从推送通知服务获得的设备令牌或注册 ID（表示移动设备和移动应用程序），以及已注册推送通知服务的移动应用程序。

凭证的准确格式因移动平台而异，但在所有情况下，这些凭证必须在与平台建立连接时提交。为每个移动应用程序发布一组凭证，并且必须将其用于将消息发送到该应用程序的所有实例。

具体名称根据使用的推送通知服务而不同。例如，当 APNs 用作推送通知服务时，您需要*设备令牌*。或者，如果使用 FCM，对应于设备令牌的是*注册 ID*。*设备令牌*或*注册 ID* 是由移动设备的操作系统发送到应用程序的字符串。它唯一标识运行在特定移动设备上的移动应用程序的实例，可以视为此应用程序/设备对的唯一标识符。

Amazon SNS 将凭证（以及其他几个设置）存储为平台应用程序资源。设备令牌（以及一些其他设置）以被称为*平台端点*的对象来表示。每个平台终端节点属于一个特定平台应用程序，可以使用存储在其对应平台应用程序中的凭证与每个平台终端节点进行通信。

下面几节包括每个受支持推送通知服务的先决条件。获得必备信息后，您可以使用 AWS 管理控制台 或 Amazon SNS 移动推送发送推送通知消息。 APIs有关更多信息，请参阅 [使用 Amazon SNS 设置推送通知](sns-mobile-application-as-subscriber.md#sns-user-notifications-process-overview)。

# 创建 Amazon SNS 平台应用程序
<a name="mobile-push-send-register"></a>

要使 Amazon SNS 向移动端点发送通知消息（无论是直接发送还是通过订阅主题），您首先都必须创建平台应用程序。在向 AWS 注册应用程序后，您需要为应用程序和移动设备都创建一个端点。此端点可让 Amazon SNS 向设备发送消息。

**要创建平台应用程序**

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航窗格中，选择**推送通知**。

1. 在 **Platform applications**（平台应用程序）部分，选择 **Create platform application**（创建平台应用程序）。

1. 选择您的 **AWS 区域**。有关可以在其中创建移动应用程序的 AWS 区域的列表，请参阅[Amazon SNS 移动应用程序支持的区域](sns-mobile-push-supported-regions.md)。

1. 输入以下**应用程序详细信息**：
   + **应用程序名称** - 提供您的平台应用程序的**名称**。名称长度在 1 到 256 个字符之间，可以包含字母（大写和小写）、数字、连字符、下划线和句号。
   + **推送通知平台** - 选择应用程序注册的相应**通知服务**（例如 Apple Push Notification Service (APNs)、Firebase Cloud Messaging (FCM)）。

1. 根据您选择的平台，您需要提供特定凭证：
   + 对于 **APNs**（Apple Push Notification Service）– 在**基于令牌的身份验证**或**基于证书的身份验证**之间进行选择。
     + 对于基于令牌的身份验证，上传 **.p8 文件**（通过 Keychain Access 生成）。
     + 对于基于证书的身份验证，上传 **.p12 文件**（也从 Keychain Access 导出）。
   + 对于 **FCM**（Firebase Cloud Messaging）– 输入来自 Firebase 控制台的**服务器密钥**。
   + 对于**其他平台**（例如 ADM 或 GCM）– 输入相应的 **API 密钥**或凭证。

1. 输入必要的详细信息后，选择**创建平台应用程序**。此操作将该应用程序注册到 Amazon SNS 并创建相应的平台应用程序对象。

1. 创建后，Amazon SNS 会生成并返回一个 [https://docs.aws.amazon.com/sns/latest/api/API_PlatformApplication.html](https://docs.aws.amazon.com/sns/latest/api/API_PlatformApplication.html)（亚马逊资源名称）。此 ARN 可唯一标识您的平台应用程序，用于为移动设备创建端点。

# 为移动通知设置 Amazon SNS 平台端点
<a name="mobile-platform-endpoint"></a>

当应用程序和移动设备注册推送通知服务（例如 APNs 或 Firebase Cloud Messaging）时，推送通知服务会返回设备令牌。Amazon SNS 使用此设备令牌创建平台端点，该端点充当向设备上的应用程序发送直接推送通知消息的目标。平台端点充当网桥，将 Amazon SNS 发送的消息路由到推送通知服务，然后传输到相应的移动设备。有关更多信息，请参阅[Amazon SNS 用户通知的先决条件](sns-prerequisites-for-mobile-push-notifications.md)和[使用 Amazon SNS 设置推送通知](sns-mobile-application-as-subscriber.md#sns-user-notifications-process-overview)。

## 了解设备令牌和平台端点
<a name="device-token-platform-endpoint"></a>

设备令牌唯一标识在推送通知服务（例如，Firebase 云消息）中注册的移动设备。 APNs当应用程序在推送通知服务中注册时，它会生成特定于该应用程序和设备的设备令牌。Amazon SNS 使用此设备令牌在相应的平台应用程序中创建平台端点。

平台端点支持 Amazon SNS 通过推送通知服务向设备发送推送通知消息，从而保持应用程序与用户设备之间的连接。

## 创建平台终端节点
<a name="mobile-platform-endpoint-create"></a>

要使用 Amazon SNS 将通知推送到应用程序，必须先通过调用创建平台终端节点操作，将该应用程序的设备令牌注册到 Amazon SNS。此操作以参数的形式获取平台应用程序的 Amazon Resource Name (ARN) 以及设备令牌，并返回所创建平台终端节点的 ARN。

[https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html) 操作会执行以下操作：
+ 如果平台端点已存在，则不重新创建。向调用方返回现有平台终端节点的 ARN。
+ 如果存在具有相同设备令牌但不同设置的平台端点，则不重新创建。向调用方引发异常。
+ 如果平台端点不存在，则创建它。向调用方返回新创建的平台终端节点的 ARN。

您不应在每次应用程序启动时立即调用创建平台终端节点操作，因为此方法并不总是提供正常工作的终端节点。例如，在相同设备上卸载并重新安装了应用程序，并且其终端节点已存在但被禁用时，会出现这种情况。成功的注册过程应该完成以下任务：

1. 确保此应用程序/设备组合存在平台终端节点。

1. 确保平台终端节点中的设备令牌是最新的有效设备令牌。

1. 确保平台终端节点已启用并且已准备好使用。

## 伪代码
<a name="mobile-platform-endpoint-pseudo-code"></a>

以下伪代码介绍了在各种各样的开始条件中创建正常工作的、当前启用的平台终端节点的推荐做法。不论应用程序是否首次注册、此应用程序的平台终端节点是否已存在、平台终端节点是否已启用、是否具有正确的设备令牌等等，此方法均适用。连续多次调用该方法是安全的，因为它不会创建重复的平台终端节点；如果现有平台终端节点已是最新的并且已启用，也不会更改它。

```
retrieve the latest device token from the mobile operating system
if (the platform endpoint ARN is not stored)
  # this is a first-time registration
  call create platform endpoint
  store the returned platform endpoint ARN
endif

call get endpoint attributes on the platform endpoint ARN 

if (while getting the attributes a not-found exception is thrown)
  # the platform endpoint was deleted 
  call create platform endpoint with the latest device token
  store the returned platform endpoint ARN
else 
  if (the device token in the endpoint does not match the latest one) or 
      (GetEndpointAttributes shows the endpoint as disabled)
    call set endpoint attributes to set the latest device token and then enable the platform endpoint
  endif
endif
```

在应用程序希望注册或重新注册自身时，可以随时使用此方法。它还可在向 Amazon SNS 通知设备令牌更改时使用。在这种情况下，只需使用最新的设备令牌值调用操作即可。有关此方法需要说明的几点是：
+ 在两种情况下可能会调用创建平台终端节点操作。在刚开始时，应用程序不知道自己的平台终端节点 ARN 时可能会调用该方法；这种情况出现在首次注册期间。在初始 `GetEndpointAttributes` 操作失败并返回“未找到”异常时，也会调用该方法；这种情况发生在应用程序知道其端点 ARN 但该 ARN 已被删除时。
+ 调用 `GetEndpointAttributes` 操作来验证平台端点的状态，即使刚刚创建了平台端点。平台终端节点已存在但被禁用时会出现这种情况。在这种情况下，创建平台终端节点操作成功，但不启用平台终端节点，因此您必须在返回成功之前仔细检查平台终端节点的状态。

## AWS SDK 示例
<a name="mobile-platform-endpoint-sdk-examples"></a>

以下代码显示了如何使用提供的 Amazon SNS 客户端来实现之前的伪代码。 AWS SDKs

要使用 S AWS DK，必须使用您的凭据对其进行配置。有关更多信息，请参阅[《工具参考指南》和《*工具参考指南》中的共享配置AWS SDKs 和*凭据文件](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html)。

------
#### [ CLI ]

**AWS CLI**  
**创建平台应用程序端点**  
以下 `create-platform-endpoint` 示例使用指定令牌为指定平台应用程序创建端点。  

```
aws sns create-platform-endpoint \
    --platform-application-arn arn:aws:sns:us-west-2:123456789012:app/GCM/MyApplication \
    --token EXAMPLE12345...
```
输出：  

```
{
      "EndpointArn": "arn:aws:sns:us-west-2:1234567890:endpoint/GCM/MyApplication/12345678-abcd-9012-efgh-345678901234"
}
```

------
#### [ Java ]

**适用于 Java 的 SDK 2.x**  
 还有更多相关信息 GitHub。在 [AWS 代码示例存储库](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples)中查找完整示例，了解如何进行设置和运行。

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.CreatePlatformEndpointRequest;
import software.amazon.awssdk.services.sns.model.CreatePlatformEndpointResponse;
import software.amazon.awssdk.services.sns.model.SnsException;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * In addition, create a platform application using the AWS Management Console.
 * See this doc topic:
 *
 * https://docs.aws.amazon.com/sns/latest/dg/mobile-push-send-register.html
 *
 * Without the values created by following the previous link, this code examples
 * does not work.
 */

public class RegistrationExample {
    public static void main(String[] args) {
        final String usage = """

            Usage:     <token> <platformApplicationArn>

            Where:
               token - The device token or registration ID of the mobile device. This is a unique 
               identifier provided by the device platform (e.g., Apple Push Notification Service (APNS) for iOS devices, Firebase Cloud Messaging (FCM) 
               for Android devices) when the mobile app is registered to receive push notifications.

               platformApplicationArn - The ARN value of platform application. You can get this value from the AWS Management Console.\s

            """;

        if (args.length != 2) {
            System.out.println(usage);
            return;
        }

        String token = args[0];
        String platformApplicationArn = args[1];
        SnsClient snsClient = SnsClient.builder()
            .region(Region.US_EAST_1)
            .build();

        createEndpoint(snsClient, token, platformApplicationArn);
    }
    public static void createEndpoint(SnsClient snsClient, String token, String platformApplicationArn) {
        System.out.println("Creating platform endpoint with token " + token);
        try {
            CreatePlatformEndpointRequest endpointRequest = CreatePlatformEndpointRequest.builder()
                .token(token)
                .platformApplicationArn(platformApplicationArn)
                .build();

            CreatePlatformEndpointResponse response = snsClient.createPlatformEndpoint(endpointRequest);
            System.out.println("The ARN of the endpoint is " + response.endpointArn());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
        }
    }
}
```

------

 有关更多信息，请参阅 [移动推送 API 操作](mobile-push-api.md)。

## 问题排查
<a name="mobile-platform-endpoint-problems"></a>

### 使用过期设备令牌重复调用创建平台终端节点操作
<a name="mobile-platform-endpoint-problems-outdated"></a>

特别是对于 FCM 端点，您可能会认为最好是存储应用程序发布的第一个设备令牌，然后在每次应用程序启动时，使用该设备令牌调用创建平台端点操作。这似乎正确，因为它会使得应用程序无需管理设备令牌的状态，Amazon SNS 自动将设备令牌更新为其最新值。但是，此解决方案存在多个严重问题：
+ Amazon SNS 依靠 FCM 的反馈将失效的设备令牌更新为新的设备令牌。FCM 会将旧设备令牌的相关信息保留一段时间，但并非无限期保留。FCM 忘掉旧设备令牌与新设备令牌之间的联系之后，Amazon SNS 无法再将存储在平台终端节点中的设备令牌更新为其正确值，而只是改为禁用平台终端节点。
+ 平台应用程序将包含与同一个设备令牌对应的多个平台终端节点。
+ Amazon SNS 对使用相同设备令牌创建的平台终端节点数量施加了配额。最终，新终端节点的创建将会失败，引发无效参数异常并显示以下错误消息：“此终端节点已注册到其他令牌。”

有关管理 FCM 端点的更多信息，请参阅 [Amazon SNS 管理 Firebase Cloud Messaging 端点](sns-fcm-endpoint-management.md)。

### 重新启用与无效设备令牌关联的平台终端节点
<a name="mobile-platform-endpoint-problems-invalid"></a>

当移动平台（例如 APNs 或 FCM）通知 Amazon SNS 发布请求中使用的设备令牌无效时，Amazon SNS 将禁用与该设备令牌关联的平台终端节点。然后，Amazon SNS 将拒绝向该设备令牌进行的后续发布操作。虽然您可能会认为最好的方法是简单地重新启用平台终端节点并保持发布，但大多数情况下这样做不会有成效：发布的消息不会被传输，平台终端节点随后很快会再次被禁用。

这是因为与平台终端节点关联的设备令牌已真正无效。由于它不再对应于任何已安装的应用程序，因此以它为目标的传输操作不会成功。下次发布到该平台终端节点时，移动平台将再次通知 Amazon SNS 设备令牌无效，Amazon SNS 将再次禁用该平台终端节点。

要重新启用已禁用的平台终端节点，该终端节点需要关联到有效的设备令牌（使用设置终端节点属性操作调用），然后再启用。只有这样，以该平台终端节点为目标的传输操作才会成功。要在不更新设备令牌的情况下重新启用平台终端节点，这种方法只有当与终端节点关联的设备令牌曾经无效但重新变得有效时才有起作用。例如，在相同移动设备上卸载、然后重新安装了某个应用程序并收到了相同的设备令牌时，会出现这种情况。上述方法会执行此操作，确保只有在验证与某个平台终端节点关联的设备令牌是最新可用的设备令牌时，才重新启用该平台终端节点。

# 将设备令牌与 Amazon SNS 集成以发送移动通知
<a name="mobile-push-send-devicetoken"></a>

当您首次使用通知服务（例如 Apple 推送通知服务 (APNs) 和 Firebase Cloud Messaging (FCM)）注册应用程序和移动设备时，该服务会返回设备令牌或注册 IDs 信息。 tokens/IDs 它们将添加到 Amazon SNS 中，以便使用 API 为应用程序和设备创建终端节点。[https://docs.aws.amazon.com/sns/latest/api/API_PlatformApplication.html](https://docs.aws.amazon.com/sns/latest/api/API_PlatformApplication.html)端点创建完成后，系统会返回一个 [https://docs.aws.amazon.com/sns/latest/api/API_Endpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_Endpoint.html)，Amazon SNS 就会使用它将通知发送到对应的应用程序或设备。

您可以通过以下方式向 Amazon SNS 添加设备令牌或注册 IDs ：
+ 通过手动添加单个令牌 AWS 管理控制台
+ 使用 [https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html) API 上传多个令牌
+ 为未来的设备注册令牌

****手动添加设备令牌或注册 ID****

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航窗格中，选择**推送通知**。

1. 在**平台应用程序**部分，选择您的应用程序，然后选择**编辑**。如果您尚未创建平台应用程序，请按照[创建 Amazon SNS 平台应用程序](mobile-push-send-register.md)指南立即创建。

1. 选择**创建端点**。

1. 在**Endpoint Token**（端点令牌）框中，输入**令牌**或**注册 ID**，具体取决于您使用的通知服务（例如，FCM 注册 ID）。

1. （可选）在 **User Data**（用户数据）字段中输入其他数据。数据必须采用 UTF-8 编码并且小于 2KB。

1. 选择**创建端点**。

创建了端点后，您可以直接向移动设备发送消息，也可以向订阅了某一 Amazon SNS 主题的移动设备发送消息。

****使用 `CreatePlatformEndpoint` API 上传多个令牌****

以下步骤说明如何使用提供的示例 Java 应用程序（`bulkupload`软件包）将多个令牌（设备令牌或注册 IDs）上传 AWS 到 Amazon SNS。您可以使用本示例应用帮助您开始上传现有令牌。
**注意**  
下面的步骤使用 Eclipse Java IDE。这些步骤假设您已安装 适用于 Java 的 AWS SDK 并且拥有自己的 AWS 安全证书 AWS 账户。有关更多信息，请参阅 [适用于 Java 的 AWS SDK](https://aws.amazon.com/sdkforjava/)。有关更多信息，请参阅《IAM 用户指南》**中的 [AWS 安全性凭证](https://docs.aws.amazon.com/general/latest/gr/getting-aws-sec-creds.html)。

1. 下载并解压缩 [snsmobilepush.zip](samples/snsmobilepush.zip) 文件。

1. 在 Eclipse 中创建一个新的 **Java 项目**，然后将 `SNSSamples` 文件夹导入到该项目中。

1. 下载 [OpenCSV 库](http://sourceforge.net/projects/opencsv/)，并添加到生成路径中。

1. 在 `BulkUpload.properties` 文件中，指定以下项：
   + 您的 `ApplicationArn`（平台应用程序 ARN）。
   + 包含令牌的 CSV 文件的绝对路径。
   + 记录成功和失败令牌的文件名。例如，`goodTokens.csv` 和 `badTokens.csv`。
   + （可选）用于设置分隔符、引用字符以及线程数量的配置。

   完成后的 `BulkUpload.properties` 与下文类似：

   ```
   applicationarn: arn:aws:sns:us-west-2:111122223333:app/FCM/fcmpushapp
   csvfilename: C:\\mytokendirectory\\mytokens.csv
   goodfilename: C:\\mylogfiles\\goodtokens.csv
   badfilename: C:\\mylogfiles\\badtokens.csv
   delimiterchar: ','
   quotechar: '"'
   numofthreads: 5
   ```

1.  运行 **BatchCreatePlatformEndpointSample.java** 应用程序将令牌上传到亚马逊 SNS。成功上传的令牌将记录在 `goodTokens.csv` 中，而格式错误的令牌将记录在 `badTokens.csv` 中。

**为未来的应用程序安装注册设备令牌**

您可以通过以下两个选项来执行此操作：

**使用 Amazon Cognito 服务**  
您的移动应用程序可以使用临时安全凭证来创建端点。建议使用 Amazon Cognito 来生成临时凭证。有关更多信息，请参阅 *[Amazon Cognito 开发人员指南](https://docs.aws.amazon.com/cognito/latest/developerguide/)*。  
要跟踪应用程序[注册](application-event-notifications.md)，请在创建新的 ARNs 终端节点时使用 Amazon SNS 事件接收通知。  
或者，您可以使用 [https://docs.aws.amazon.com/sns/latest/api/API_ListEndpointsByPlatformApplication.html](https://docs.aws.amazon.com/sns/latest/api/API_ListEndpointsByPlatformApplication.html) API 检索已注册的端点列表。

**使用代理服务器**  
如果您的应用程序基础架构已支持在安装时注册设备，则可以将服务器用作代理。它将通过 [https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html) API 将设备令牌转发给 Amazon SNS。  
Amazon SNS 创建的端点 ARN 将被返回，并可由您的服务器存储起来，以便未来发布消息时使用。

# Amazon SNS Apple 推送通知身份验证方法
<a name="sns-apple-authentication-methods"></a>

您可以通过提供将您识别为应用程序开发人员的信息，授权 Amazon SNS 将推送通知发送到您的 iOS 或 macOS 应用程序。要进行身份验证，请[在创建平台应用程序时](https://docs.aws.amazon.com/sns/latest/api/API_SetPlatformApplicationAttributes.html)提供*密钥*或者*证书*，您可以通过 Apple 开发人员账户获得这两项。

**令牌签名密钥**  
Amazon SNS 用于签署 Apple 推送通知服务 (APNs) 身份验证令牌的私有签名密钥。  
如果您提供签名密钥，Amazon SNS 将使用令牌对您发送 APNs的每条推送通知进行身份验证。使用您的签名密钥，您可以向 APNs 生产环境和沙盒环境发送推送通知。  
您的签名密钥不会过期，您可以将相同的签名密钥用于多个应用程序。有关更多信息，请参阅 Apple 网站 “**开发者账户帮助**” 部分中的[ APNs 使用身份验证令牌进行通信](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns)。

**证书**  
在您发送推送通知 APNs 时，Amazon SNS 使用它进行身份验证的 TLS 证书。您可以从 Apple 开发人员账户获取该证书。  
证书将在一年后过期。出现这种情况时，您必须创建新证书并将其提供给 Amazon SNS。有关更多信息，请参阅 Apple 开发者网站 APNs上的[与建立基于证书的连接](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns)。

**使用管理控制台 AWS 管理 APNs 设置**

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航窗格中，选择**推送通知**。

1. 在**平台应用程序**部分，选择要编辑其 APNs 设置的**应用程序**，然后选择**编辑**。如果您尚未创建平台应用程序，请按照[创建 Amazon SNS 平台应用程序](mobile-push-send-register.md)指南立即创建。

1. 选择**编辑**以修改平台应用程序的设置。

1. 在**身份验证类型**部分，选择下列选项之一：
   + **基于令牌的身份验证**（建议用于现代 APNs 集成）
   + **基于证书的身份验证**（旧方法）

1. 根据身份验证类型配置您的**凭证**：
   + **基于令牌的身份验证**：
     + 上传 **.p8 文件**，这是您从 Apple 开发者帐户下载的身份验证令牌签名密钥。
     + 输入**签名密钥 ID**，您可以在 Apple 开发者账户中找到它。导航到 “**证书**” **IDs、“配置文件**”、“**密钥**”，然后选择要使用的**密**钥。
     + 提供 Apple 开发人员账户中的**团队标识符**。可以在“会员资格”页面上找到此值。
     + 输入分配给您的应用程序的**捆绑标识符**。您可以在 “证书” IDs 和 “配置文件”、“应用程序” 下找到此信息 IDs。
   + **基于证书的身份验证：**
     + 上传您的 TLS 证书的 **.p12 文件**。当您从 Apple 开发人员账户下载证书之后，可以在 macOS 上从 Keychain Access 导出此文件。
     + 如果您的 .p12 证书设置了**密码**，在这里输入它。

1. 输入必要的凭证后，选择**保存更改**以更新设置。

# Amazon SNS 与 Firebase Cloud Messaging 身份验证设置集成
<a name="sns-fcm-authentication-methods"></a>

本主题介绍如何从 Google 获取用于该 API 所需的 FCM API (HTTP v1) 凭据， AWS CLI 以及。 AWS AWS 管理控制台

**重要**  
2024 年 3 月 26 日 – Amazon SNS 支持适用于 Apple 设备和 Webpush 目的地的 FCM HTTP v1 API。我们建议您在 2024 年 6 月 1 日或之前将现有的移动推送应用程序迁移到最新的 FCM HTTP v1 API，以避免应用程序中断。  
2024 年 1 月 18 日 – Amazon SNS 推出了对 FCM HTTP v1 API 的支持，用于向 Android 设备发送移动推送通知。  
2023 年 6 月 20 日 - Google 弃用了其 Firebase Cloud Messaging（FCM）旧版 HTTP API。Amazon SNS 现在支持使用 FCM HTTP v1 API 向所有设备类型传送。我们建议您在 2024 年 6 月 1 日或之前将现有的移动推送应用程序迁移到最新的 FCM HTTP v1 API，以避免中断。

您可以通过提供将您识别为应用程序开发人员的信息，授权 Amazon SNS 将推送通知发送到您的应用程序。要进行身份验证，请在[创建平台应用程序时](https://docs.aws.amazon.com/sns/latest/api/API_SetPlatformApplicationAttributes.html)提供 **API 密钥**或**令牌**。您可以从 [Firebase 应用程序控制台](https://firebase.google.com/?gad=1&gclid=CjwKCAiA0syqBhBxEiwAeNx9N27M7zxHjlS74_gp4mAS4QTMQH5J35sTO29od-yauuq259zzX_I2DRoCrbsQAvD_BwE&gclsrc=aw.ds)获取以下信息：

**API 密钥**  
API 密钥是调用 Firebase 的旧版 API 时使用的凭证。谷歌 APIs 将于2024年6月20日移除FCM Legacy。如果您当前使用 API 密钥作为平台凭证，则可以通过选择**令牌**作为选项并上传您的 Firebase 应用程序的关联 JSON 文件来更新平台凭证。

**令牌**  
在调用 HTTP v1 API 时，会使用有效期很短的访问令牌。这是 Firebase 的建议用于发送推送通知的 API。为了生成访问令牌，Firebase 以私有密钥文件（也称为 service.json 文件）的形式为开发人员提供了一组凭证。

## 先决条件
<a name="sns-fcm-authentication-prerequisite"></a>

您必须先获取 FCM service.json 凭证，然后才能开始在 Amazon SNS 中管理 FCM 设置。要获取您的 service.json 凭据，请参阅谷歌 Firebase 文档中的[从旧版 FCM 迁移 APIs 到 HTTP v1](https://firebase.google.com/docs/cloud-messaging/migrate-v1)。

## 使用 CLI 管理 FCM 设置
<a name="sns-fcm-authentication-api"></a>

您可以使用 AWS API 创建 FCM 推送通知。一个 AWS 账户中 Amazon SNS 资源的数量和大小是有限的。有关更多信息，请参阅《AWS 一般参考 Guide》**中的 [Amazon Simple Notification Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/sns.html)。

**创建 FCM 推送通知以及亚马逊 SNS 主题AWS (API)**  
使用**密钥**凭证时，`PlatformCredential` 为 `API key`。使用**令牌**凭证时，`PlatformCredential` 为一个采用 JSON 格式的私有密钥文件：
+ [https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)

**检索现有亚马逊 SNS 主题 (API) 的 FCM 凭证类型AWS**  
检索凭证类型 `"AuthenticationMethod": "Token"` 或 ` "AuthenticationMethod": "Key"`：
+ [GetPlatformApplicationAttributes](https://docs.aws.amazon.com/sns/latest/api/API_GetPlatformApplicationAttributes.html)

**为现有亚马逊 SNS 主题AWS (API) 设置 FCM 属性**  
设置 FCM 属性：
+ [SetPlatformApplicationAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetPlatformApplicationAttributes.html)

## 使用控制台管理 FCM 设置
<a name="sns-fcm-authentication-cli"></a>

您可以使用 AWS Command Line Interface (CLI) 创建 FCM 推送通知。一个 AWS 账户中 Amazon SNS 资源的数量和大小是有限的。有关更多信息，请参阅 [Amazon Simple Notification Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/sns.html)。

**与 Amazon SNS 主题一起创建 FCM 推送通知（AWS CLI）**  
使用**密钥**凭证时，`PlatformCredential` 为 `API key`。使用**令牌**凭证时，`PlatformCredential` 为一个采用 JSON 格式的私有密钥文件。使用 AWS CLI 时，文件必须为字符串格式，并且必须忽略特殊字符。为了正确格式化文件，Amazon SNS 建议使用以下命令：`SERVICE_JSON=`jq @json <<< cat service.json``：
+ [create-platform-application](https://docs.aws.amazon.com/cli/latest/reference/sns/create-platform-application.html)

**检索现有 Amazon SNS 主题的 FCM 凭证类型（AWS CLI）**  
检索凭证类型 `"AuthenticationMethod": "Token"` 或 ` "AuthenticationMethod": "Key"`：
+ [get-platform-application-attributes](https://docs.aws.amazon.com/cli/latest/reference/sns/get-platform-application-attributes.html)

**为现有 Amazon SNS 主题设置 FCM 属性（AWS CLI）**  
设置 FCM 属性：
+ [set-platform-application-attributes](https://docs.aws.amazon.com/cli/latest/reference/sns/set-platform-application-attributes.html)

## 管理 FCM 设置（控制台）
<a name="sns-fcm-authentication-console"></a>

按照以下步骤在 Amazon SNS 中输入和管理您的 Firebase Cloud Messaging（FCM）凭证。

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航窗格中，选择**推送通知**。

1. 在**平台应用程序**部分，选择要编辑其凭证的 **FCM 平台应用程序**，然后选择**编辑**。

1. 在 **Firebase Cloud Messaging 凭证**部分，选择以下选项之一：
   + **基于令牌的身份验证**（推荐方法）：上传您从 Firebase 控制台下载的**私钥文件**（JSON）。此文件包含用于生成发送 FCM 通知所需的短期访问令牌的凭证。要获取此文件，请执行以下操作：

     1. 前往您的 [Firebase 应用程序控制台](https://firebase.google.com/?gad=1&gclid=CjwKCAiA0syqBhBxEiwAeNx9N27M7zxHjlS74_gp4mAS4QTMQH5J35sTO29od-yauuq259zzX_I2DRoCrbsQAvD_BwE&gclsrc=aw.ds)。

     1. 在**项目设置**中，选择**云消息传递**。

     1. 下载**私钥** JSON 文件（用于基于令牌的身份验证方法）。
   + **API 密钥身份验证** – 如果您更喜欢使用较旧的 API 密钥身份验证方法，请在提供的字段中输入 **Google API 密钥**。要获取此文件，请执行以下操作：

     1. 前往您的 [Firebase 应用程序控制台](https://firebase.google.com/?gad=1&gclid=CjwKCAiA0syqBhBxEiwAeNx9N27M7zxHjlS74_gp4mAS4QTMQH5J35sTO29od-yauuq259zzX_I2DRoCrbsQAvD_BwE&gclsrc=aw.ds)。

     1. 在**项目设置**中，选择**云消息传递**。

     1. 复制用于发送通知的**服务器密钥**（API 密钥）。

1. 完成后，选择**保存更改**。

**相关主题**
+ [在 Amazon SNS 中使用 Google Firebase Cloud Messaging v1 有效载荷](sns-fcm-v1-payloads.md)

# Amazon SNS 管理 Firebase Cloud Messaging 端点
<a name="sns-fcm-endpoint-management"></a>

## 管理和维护设备令牌
<a name="sns-managing-device-tokens"></a>

您可以按照以下步骤确保移动应用程序的推送通知的可送达性：

1. 将所有设备令牌、相应的 Amazon SNS 终端节点 ARNs和时间戳存储在您的应用程序服务器上。

1. 移除所有陈旧的令牌并删除相应的 Amazon SNS ARNs 终端节点。

应用程序首次启动后，您将收到该设备的设备令牌（也称为注册令牌）。此设备令牌由设备的操作系统创建，并与您的 FCM 应用程序相关联。收到此设备令牌后，您可以将其作为平台端点注册到 Amazon SNS。我们建议您存储设备令牌、Amazon SNS 平台端点 ARN 和时间戳，方法是将它们保存到您的应用程序服务器或其他永久存储中。要设置 FCM 应用以检索和存储设备令牌，请参阅 Google 的 *Firebase* 文档中的[检索和存储注册令牌](https://firebase.google.com/docs/cloud-messaging/manage-tokens#retrieve-and-store-registration-tokens)。

维护 up-to-date代币很重要。如果满足以下条件，用户的设备令牌可以更改：

1. 移动应用程序将在新设备上恢复。

1. 用户卸载或更新应用程序。

1. 用户清除应用程序数据。

当您的设备令牌发生变化时，我们建议您使用新令牌更新相应的 Amazon SNS 端点。这样，Amazon SNS 就可以继续与注册的设备进行通信。您可以通过在移动应用程序中实现以下伪代码来做到这一点。它描述了创建和维护已启用的平台端点的推荐做法。这种方法可以在每次移动应用程序启动时执行，也可以在后台作为计划任务执行。

### 伪代码
<a name="sns-device-token-pseudo-code"></a>

使用以下 FCM 伪代码管理和维护设备令牌。

```
retrieve the latest token from the mobile OS
if (endpoint arn not stored)
    # first time registration
    call CreatePlatformEndpoint
    store returned endpoint arn
endif

call GetEndpointAttributes on the endpoint arn 

if (getting attributes encountered NotFound exception)
    #endpoint was deleted 
    call CreatePlatformEndpoint
    store returned endpoint arn
else 
    if (token in endpoint does not match latest) or 
        (GetEndpointAttributes shows endpoint as disabled)
        call SetEndpointAttributes to set the 
                     latest token and enable the endpoint
    endif
endif
```

要详细了解令牌更新要求，请参阅 Google 的 *Firebase* 文档中的[定期更新令牌](https://firebase.google.com/docs/cloud-messaging/manage-tokens#update-tokens-on-a-regular-basis)。

## 检测令牌无效
<a name="sns-detecting-invalid-tokens"></a>

当向带有无效设备令牌的 FCM v1 端点发送消息时，Amazon SNS 将收到以下例外情况之一：
+ `UNREGISTERED`（HTTP 404）– 当 Amazon SNS 收到此异常时，您将收到一个传输失败事件，该事件的 `FailureType` 为 `InvalidPlatformToken`，且 `FailureMessage` 为*与端点关联的平台令牌无效*。当传送失败时，Amazon SNS 将禁用您的平台端点，但有此例外情况。
+ `INVALID_ARGUMENT`（HTTP 400）– 当 Amazon SNS 收到此异常时，这意味着设备令牌或消息有效载荷无效。有关更多信息，请参阅[ErrorCode](https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode)谷歌的 *Firebase* 文档。

由于在这两种情况下都可以返回 `INVALID_ARGUMENT`，因此 Amazon SNS 将返回 `InvalidNotification` `FailureType` 以及*通知正文无效* `FailureMessage`。当您收到此错误时，请验证您的有效载荷是否正确。如果正确，请验证设备令牌是否正确 up-to-date。当传送失败时，Amazon SNS 不会禁用您的平台端点，但有此例外情况。

您会遇到 `InvalidPlatformToken` 传送失败事件的另一种情况是，注册的设备令牌不属于尝试发送该消息的应用程序。在这种情况下，Google 将返回 *SENDER\$1ID\$1MISMATCH* 错误。当传送失败时，Amazon SNS 将禁用您的平台端点，但有此例外情况。

当您为应用程序设置[交付状态日志 CloudWatch](topics-attrib.md)时，可以查看从 FCM v1 API 收到的所有观察到的错误代码。

要接收应用程序的传送事件，请参阅[可用应用程序事件](application-event-notifications.md#application-event-notifications-events)。

## 移除过时令牌
<a name="sns-removing-stale-tokens"></a>

一旦向端点设备传送消息开始失败，令牌就会被视为过时。Amazon SNS 将这些过时令牌设置为您的平台应用程序的禁用端点。当您向已禁用的端点发布内容时，Amazon SNS 将返回一个 `EventDeliveryFailure` 事件，该事件的 `FailureType` 为 `EndpointDisabled`，`FailureMessage` 为*端点处于禁用状态*。要接收应用程序的传送事件，请参阅[可用应用程序事件](application-event-notifications.md#application-event-notifications-events)。

当您收到来自 Amazon SNS 的此错误时，您需要移除或更新平台应用程序中的过时令牌。

# 使用 Amazon SNS 发送移动推送通知
<a name="mobile-push-notifications"></a>

 本部分描述如何发送移动推送通知消息。

## 向主题发布
<a name="mobile-push-send-topicmobile"></a>

您还可以使用 Amazon SNS 向订阅了某一主题的移动终端节点发送消息。其概念与订阅其他终端节点类型（如 Amazon SQS、HTTP/S、电子邮件和 SMS）相同，如 [什么是 Amazon SNS？](welcome.md) 中所述。不同之处在于，Amazon SNS 通过 Apple Push Notification Service (APNS) 和 Google Firebase Cloud Messaging (FCM) 等通知服务进行通信。通过通知服务通信，订阅的移动端点可以接收发送给相应主题的通知。

## 直接 Amazon SNS 移动设备消息传递
<a name="mobile-push-send-directmobile"></a>

您可以将 Amazon SNS 推送通知消息直接发送到代表移动设备上的应用程序的端点。

**发送直送消息**

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航面板中，选择 **Push notifications**（推送通知）。

1. 例如，在**移动推送通知**页面的**平台应用程序**部分，选择应用程序的名称***MyApp***。

1. 在该***MyApp***页面的**终端节点**部分，选择终端节点，然后选择**发布消息**。

1. 在 **Publish message to endpoint (向终端节点发布消息)** 页面上，输入将显示在移动设备上的应用程序中的消息，然后选择**发布消息**。

   Amazon SNS 将通知消息发送到平台通知服务，而平台通知服务会将该消息发送到应用程序。

# 使用特定于平台的有效载荷发布 Amazon SNS 通知
<a name="sns-send-custom-platform-specific-payloads-mobile-devices"></a>

您可以使用 AWS 管理控制台 或 Amazon SNS APIs 向移动设备发送包含特定平台负载的自定义消息。有关使用 Amazon SNS 的信息 APIs，请参阅[移动推送 API 操作](mobile-push-api.md)和中的`SNSMobilePush.java`文件。`[snsmobilepush.zip](samples/snsmobilepush.zip)`

## 发送 JSON 格式化的消息
<a name="mobile-push-send-json"></a>

在发送平台特定的负载时，数据必须格式化为 JSON 键-值对字符串（用引号进行转义）。

下面的示例显示 FCM 平台的一条自定义消息。

```
{
"GCM": "{\"fcmV1Message\": {\"message\": {\"notification\": {\"title\": \"Hello\", \"body\": \"This is a test.\"}, \"data\": {\"dataKey\": \"example\"}}}}"
}
```

## 发送平台特定的消息
<a name="mobile-push-send-platform"></a>

除了以键-值对形式发送自定义数据之外，您还可以发送平台特定的键-值对。

以下示例显示如何在 FCM `data` 参数中的自定义数据键-值对之后加入 FCM 参数 `time_to_live` 和 `collapse_key`。

```
{
"GCM": "{\"fcmV1Message\": {\"message\": {\"notification\": {\"title\": \"TitleTest\", \"body\": \"Sample message for Android or iOS endpoints.\"}, \"data\":{\"time_to_live\": 3600,\"collapse_key\":\"deals\"}}}}"
}
```

有关 Amazon SNS 中支持的每个推送通知服务所支持的键-值对列表，请参阅以下内容：

**重要**  
Amazon SNS 现在支持 Firebase Cloud Messaging（FCM）HTTP v1 API，用于向 Android 设备发送移动推送通知。  
2024 年 3 月 26 日 – Amazon SNS 支持适用于 Apple 设备和 Webpush 目的地的 FCM HTTP v1 API。我们建议您在 2024 年 6 月 1 日或之前将现有的移动推送应用程序迁移到最新的 FCM HTTP v1 API，以避免应用程序中断。
+  APNs 文档中的@@ [有效载荷密钥参考](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html#/apple_ref/doc/uid/TP40008194-CH17-SW1)
+ FCM 文档中的 [Firebase 云消息收发 HTTP 协议](https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages)
+ ADM 文档中的[发送消息](https://developer.amazon.com/sdk/adm/sending-message.html)

## 在多个平台上向应用程序发送消息
<a name="mobile-push-send-multiplatform"></a>

要向安装在多个平台（例如 FCM 和）设备上的应用程序发送消息 APNs，您必须先在移动终端节点上订阅 Amazon SNS 中的主题，然后将消息发布到该主题。

以下示例显示了向 FCM 和 ADM 上 APNs订阅的移动终端节点发送的消息：

```
{ 
  "default": "This is the default message which must be present when publishing a message to a topic. The default message will only be used if a message is not present for 
one of the notification platforms.",     
  "APNS": "{\"aps\":{\"alert\": \"Check out these awesome deals!\",\"url\":\"www.amazon.com\"} }",
  "GCM": "{\"data\":{\"message\":\"Check out these awesome deals!\",\"url\":\"www.amazon.com\"}}",
  "ADM": "{\"data\":{\"message\":\"Check out these awesome deals!\",\"url\":\"www.amazon.com\"}}" 
}
```

## 将消息 APNs 作为警报或后台通知发送到
<a name="mobile-push-send-message-apns-background-notification"></a>

Amazon SNS 可以向广告 APNs 发送消息`alert`或`background`通知（有关更多信息，请参阅 APNs 文档中的[将后台更新推送到您的应用程序](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app)）。
+ `alert` APNs 通知通过显示警报消息、播放声音或在应用程序的图标上添加徽章来通知用户。
+ `background` APNs 通知会被唤醒或指示您的应用程序根据通知的内容采取行动，而不通知用户。

### 指定自定义 APNs 标题值
<a name="specify-custom-header-value"></a>

我们建议使用 Amazon SNS `Publish` API 操作为`AWS.SNS.MOBILE.APNS.PUSH_TYPE`[保留消息属性](sns-message-attributes.md#sns-attrib-mobile-reserved)指定自定义值 AWS SDKs，或。 AWS CLI以下 CLI 示例为指定的主题将 `content-available` 设置为 `1` 并将 `apns-push-type` 设置为 `background`。

```
aws sns publish \
--endpoint-url https://sns.us-east-1.amazonaws.com \
--target-arn arn:aws:sns:us-east-1:123456789012:endpoint/APNS_PLATFORM/MYAPP/1234a567-bc89-012d-3e45-6fg7h890123i \
--message '{"APNS_PLATFORM":"{\"aps\":{\"content-available\":1}}"}' \
--message-attributes '{ \
  "AWS.SNS.MOBILE.APNS.TOPIC":{"DataType":"String","StringValue":"com.amazon.mobile.messaging.myapp"}, \
  "AWS.SNS.MOBILE.APNS.PUSH_TYPE":{"DataType":"String","StringValue":"background"}, \
  "AWS.SNS.MOBILE.APNS.PRIORITY":{"DataType":"String","StringValue":"5"}}' \
--message-structure json
```

**注意**  
确保 JSON 结构有效。在每个键/值对（最后一个除外）后面添加一个逗号。

### 根据有效载荷 APNs 推断推送类型标头
<a name="inferring-push-type-header-from-payload"></a>

如果您未设置`apns-push-type` APNs 标头，Amazon SNS 会`background`根据您的 JSON 格式的负载 APNs 配置`aps`字典中的`content-available`密钥将标头设置为`alert`或依据。

**注意**  
Amazon SNS 只能推断 `background` 或 `alert` 标头，尽管 `apns-push-type` 标头可以设置为其他值。
+ `apns-push-type` 设置为 `alert`
  + 如果 `aps` 字典包含设置为 `1` 的 `content-available` 和*一个或多个*触发用户交互的键。
  + 如果 `aps` 字典包含设置为 `0` 的 `content-available` *或*如果 `content-available` 密钥不存在。
  + 如果 `content-available` 键的值不是整数或布尔值。
+ `apns-push-type` 设置为 `background`
  + 如果 `aps` 字典*仅*包含设置为 `1` 的 `content-available` 且不包含触发用户交互的*其他键*。
**重要**  
如果 Amazon SNS 将原始配置对象 APNs 作为仅限后台的通知发送，则必须在字典中包含`content-available`设置为。`1` `aps`尽管您可以包含自定义键，但 `aps` 字典不得包含触发用户交互的任何键（例如，警报、徽章或声音）。

下面是一个示例原始配置对象。

```
{
  "APNS": "{\"aps\":{\"content-available\":1},\"Foo1\":\"Bar\",\"Foo2\":123}"
}
```

在本示例中，Amazon SNS 将消息的`apns-push-type` APNs 标头设置为。`background`当 Amazon SNS 检测到 `apn` 字典包含设置为 `1` 的 `content-available` 键—并且不包含任何其他可触发用户交互的键时—它将标题设置为 `background`。

# 在 Amazon SNS 中使用 Google Firebase Cloud Messaging v1 有效载荷
<a name="sns-fcm-v1-payloads"></a>

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 有效载荷结构发送消息
<a name="sending-messages-using-v1-payload"></a>

如果您是首次创建 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 发送消息
<a name="sns-fcm-v1-legacy-payload-structure"></a>

迁移到 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 传输失败事件
<a name="sns-fcm-delivery-failure-events"></a>

下表提供了 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 操作。  | 

# Amazon SNS 移动应用程序属性
<a name="sns-msg-status"></a>

Amazon Simple Notification Service (Amazon SNS) 支持记录推送通知消息的传输状态。配置应用程序属性后，从 Amazon SNS 发送到移动终端节点的消息的 CloudWatch 日志条目将发送到日志。记录消息传输状态有助于提供更好的业务洞察力，例如以下方面：
+ 了解推送通知消息是否已从 Amazon SNS 传输到推送通知服务。
+ 识别从推送通知服务发送到 Amazon SNS 的响应。
+ 确定消息停留时间（发布时间戳与将消息转交给推送通知服务之间的时间差）。

 要为消息传送状态配置应用程序属性，您可以使用 AWS 软件开发套件 (SDKs) 或查询 API。 AWS 管理控制台

## 使用配置邮件传送状态属性 AWS 管理控制台
<a name="sns-msg-console"></a>

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航面板中，指向**移动**，并选择**推送通知**。

1. 从**平台应用程序**部分，选择包含要接收 CloudWatch 日志的终端节点的应用程序。

1. 选择 **Application Actions (应用程序操作)**，然后选择 **Delivery Status (传输状态)**。

1. 在**传输状态**对话框中，选择**创建 IAM 角色**。

   随后您将被重定向至 IAM 控制台。

1. 选择 “**允许**”，授予 Amazon SNS 写入权限，让您可以代表您使用 CloudWatch 日志。

1. 现在，返回 “**传送状态**” 对话框中，在 “**成功样本百分比 (0-100)**” 字段中输入一个数字，表示要接收 CloudWatch 日志的成功发送邮件的百分比。
**注意**  
为消息传送状态配置应用程序属性后，所有失败的消息传送都会生成 CloudWatch 日志。

1. 最后，选择**保存配置**。现在，您将能够查看和解析包含消息传送状态的 CloudWatch 日志。有关使用的更多信息 CloudWatch，请参阅[CloudWatch文档](https://aws.amazon.com/documentation/cloudwatch)。

## Amazon SNS 消息传输状态日志示例 CloudWatch
<a name="sns-msg-examples"></a>

为应用程序终端节点配置消息传送状态属性后，将生成 CloudWatch 日志。示例日志采用 JSON 格式，如下所示：

**SUCCESS**

```
{
  "status": "SUCCESS",
  "notification": {
    "timestamp": "2015-01-26 23:07:39.54",
    "messageId": "9655abe4-6ed6-5734-89f7-e6a6a42de02a"
  },
  "delivery": {
    "statusCode": 200,
    "dwellTimeMs": 65,
    "token": "Examplei7fFachkJ1xjlqT64RaBkcGHochmf1VQAr9k-IBJtKjp7fedYPzEwT_Pq3Tu0lroqro1cwWJUvgkcPPYcaXCpPWmG3Bqn-wiqIEzp5zZ7y_jsM0PKPxKhddCzx6paEsyay9Zn3D4wNUJb8m6HXrBf9dqaEw",
    "attempts": 1,
    "providerResponse": "{\"multicast_id\":5138139752481671853,\"success\":1,\"failure\":0,\"canonical_ids\":0,\"results\":[{\"message_id\":\"0:1422313659698010%d6ba8edff9fd7ecd\"}]}",
    "destination": "arn:aws:sns:us-east-2:111122223333:endpoint/FCM/FCMPushApp/c23e42de-3699-3639-84dd-65f84474629d"
  }
}
```

**FAILURE**

```
{
  "status": "FAILURE",
  "notification": {
    "timestamp": "2015-01-26 23:29:35.678",
    "messageId": "c3ad79b0-8996-550a-8bfa-24f05989898f"
  },
  "delivery": {
    "statusCode": 8,
    "dwellTimeMs": 1451,
    "token": "examp1e29z6j5c4df46f80189c4c83fjcgf7f6257e98542d2jt3395kj73",
    "attempts": 1,
    "providerResponse": "NotificationErrorResponse(command=8, status=InvalidToken, id=1, cause=null)",
    "destination": "arn:aws:sns:us-east-2:111122223333:endpoint/APNS_SANDBOX/APNSPushApp/986cb8a1-4f6b-34b1-9a1b-d9e9cb553944"
  }
}
```

有关推送通知服务响应代码的列表，请参阅[平台响应代码](#platform-returncodes)。

## 使用配置消息传送状态属性 AWS SDKs
<a name="sns-msg-sdk"></a>

[AWS SDKs](https://aws.amazon.com/tools/)提供了多种语言版本，用于 APIs 在 Amazon SNS 中使用消息传送状态属性。

下面的 Java 示例显示了如何使用 `SetPlatformApplicationAttributes` API 为推送通知消息的消息传输状态配置应用程序属性。您可以对消息传输状态使用以下属性：`SuccessFeedbackRoleArn`、`FailureFeedbackRoleArn` 和 `SuccessFeedbackSampleRate`。`SuccessFeedbackRoleArn`和`FailureFeedbackRoleArn`属性用于向 Amazon SNS 授予代表您使用 CloudWatch 日志的写入权限。`SuccessFeedbackSampleRate` 属性用于指定成功传输消息的采样率百分比 (0-100)。配置该`FailureFeedbackRoleArn`属性后，所有失败的消息传送都会生成 CloudWatch 日志。

```
SetPlatformApplicationAttributesRequest setPlatformApplicationAttributesRequest = new SetPlatformApplicationAttributesRequest();
Map<String, String> attributes = new HashMap<>();
attributes.put("SuccessFeedbackRoleArn", "arn:aws:iam::111122223333:role/SNS_CWlogs");
attributes.put("FailureFeedbackRoleArn", "arn:aws:iam::111122223333:role/SNS_CWlogs");
attributes.put("SuccessFeedbackSampleRate", "5");
setPlatformApplicationAttributesRequest.withAttributes(attributes);
setPlatformApplicationAttributesRequest.setPlatformApplicationArn("arn:aws:sns:us-west-2:111122223333:app/FCM/FCMPushApp");
sns.setPlatformApplicationAttributes(setPlatformApplicationAttributesRequest);
```

有关适用于 Java 的开发工具包的更多信息，请参阅 [适用于 Java 的 AWS SDK入门指南](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html)。

## 平台响应代码
<a name="platform-returncodes"></a>

下面是推送通知服务响应代码链接列表：


****  

| 推送通知服务 | 响应代码 | 
| --- | --- | 
| Amazon Device Messaging（ADM） | 请参阅 ADM 文档中的[响应格式](https://developer.amazon.com/docs/adm/send-message.html#response-format)。 | 
| 苹果推送通知服务 (APNs) | 请参阅《本地和远程通知编程指南》 APNs中的 “[与之通信](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#/apple_ref/doc/uid/TP40008194-CH11-SW1)” APNs 中的 HTTP/2 响应。 | 
| Firebase Cloud Messaging (FCM) | 请参阅 Firebase Cloud Messaging 文档中的[下游消息错误响应代码](https://firebase.google.com/docs/cloud-messaging/http-server-ref#error-codes) | 
| 适用于 Windows Phone 的 Microsoft 推送通知服务 (MPNS) | 请参阅 Windows 8 开发文档中的 [Windows Phone 8 的推送通知服务响应代码](https://msdn.microsoft.com/en-us/library/windows/apps/ff941100%28v=vs.105%29.aspx#BKMK_PushNotificationServiceResponseCodes)。 | 
| Windows 推送通知服务 (WNS) | 请参阅 Windows 8 开发文档中[推送通知服务请求和响应标头（Windows 运行时应用程序）](https://msdn.microsoft.com/en-us/library/windows/apps/hh465435.aspx)中的“响应代码”。 | 

# 移动应用程序的 Amazon SNS 应用程序事件通知
<a name="application-event-notifications"></a>

Amazon SNS 提供在发生特定应用程序事件时触发通知的支持。然后，您可以对该事件采取一些编程操作。您的应用程序必须支持推送通知服务，例如 Apple 推送通知服务 (APNs)、Firebase 云消息 (FCM) 和 Windows 推送通知服务 (WNS)。您可以使用 Amazon SNS 控制台设置应用程序事件通知 AWS CLI，或者。 AWS SDKs

## 可用应用程序事件
<a name="application-event-notifications-events"></a>

应用程序事件通知跟踪各个平台端点何时创建、删除、更新以及出现传输故障。以下是应用程序事件的属性名称。


| 属性名称 | 通知触发器 | 
| --- | --- | 
| EventEndpointCreated | 向应用程序添加新的平台端点。 | 
| EventEndpointDeleted | 删除与应用程序关联的任何平台端点。 | 
| EventEndpointUpdated | 与应用程序关联的平台端点的任何属性发生更改。 | 
| EventDeliveryFailure | 向与应用程序关联的任何平台端点的传输操作发生永久性故障。 要跟踪平台应用程序端的传输故障，需要为应用程序订阅消息传输状态事件。有关更多信息，请参阅[使用用于消息传输状态的 Amazon SNS 应用程序属性](https://docs.aws.amazon.com/sns/latest/dg/sns-msg-status.html)。  | 

您可以将任何属性与应用程序关联，然后应用程序就可以接收这些事件通知。

## 发送移动推送通知
<a name="application-event-notifications-howto-set"></a>

要发送应用程序事件通知，您需要为每种事件类型指定用于接收通知的主题。Amazon SNS 发送通知时，主题可以将它们路由至将采取编程操作的终端节点。

**重要**  
高容量应用程序将创建大量的应用程序事件通知（例如，数万条），这会“淹没”供人们使用的端点，例如电子邮件、电话号码和移动应用程序。在向主题发送应用程序事件通知时，需要考虑以下指导原则：  
每个接收通知的主题都应仅包含对编程终端节点（例如 HTTP 或 HTTPS 终端节点、Amazon SQS 队列或 AWS Lambda 函数）的订阅。
要减少通知触发的处理量，请将每个主题的订阅数限制在很小的数目（例如，五个或更少）。

您可以使用 Amazon SNS 控制台、 AWS Command Line Interface (AWS CLI) 或，发送应用程序事件通知。 AWS SDKs

### AWS 管理控制台
<a name="application-event-notifications-howto-set-console"></a>

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航面板中，选择**移动**，**推送通知**。

1. 在**移动推送通知**页面上的**平台应用程序**部分中，选择应用程序，然后选择**编辑**。

1. 展开**事件通知**部分。

1. 依次选择**操作**和**配置事件**。

1. 输入 ARNs 要用于以下事件的主题：
   + 已创建端点
   + 已删除端点
   + 已更新端点
   + 传输失败

1. 选择**保存更改**。

### AWS CLI
<a name="awscli"></a>

运行 [set-platform-application-attributes](https://docs.aws.amazon.com/cli/latest/reference/sns/set-platform-application-attributes.html) 命令。

以下示例为全部四个应用程序事件设置相同的 Amazon SNS 主题：

```
aws sns set-platform-application-attributes
--platform-application-arn arn:aws:sns:us-east-1:12345EXAMPLE:app/FCM/MyFCMPlatformApplication
--attributes EventEndpointCreated="arn:aws:sns:us-east-1:12345EXAMPLE:MyFCMPlatformApplicationEvents",
EventEndpointDeleted="arn:aws:sns:us-east-1:12345EXAMPLE:MyFCMPlatformApplicationEvents",
EventEndpointUpdated="arn:aws:sns:us-east-1:12345EXAMPLE:MyFCMPlatformApplicationEvents",
EventDeliveryFailure="arn:aws:sns:us-east-1:12345EXAMPLE:MyFCMPlatformApplicationEvents"
```

### AWS SDKs
<a name="application-event-notifications-sdk"></a>

通过使用软件开发工具包向 Amazon SNS API 提交`SetPlatformApplicationAttributes`请求来设置应用程序事件通知。 AWS 

有关 AWS SDK 开发者指南和代码示例的完整列表，包括入门帮助和有关先前版本的信息，请参阅[将 Amazon SNS 与软件开发工具包配合使用 AWS](sdk-general-information-section.md)。

# 移动推送 API 操作
<a name="mobile-push-api"></a>

要使用 Amazon SNS 移动推送 API，必须首先满足推送通知服务（如 Apple Push Notification Service (APNs) 和 Firebase Cloud Messaging (FCM)）的先决条件。有关这些先决条件的更多信息，请参阅[Amazon SNS 用户通知的先决条件](sns-prerequisites-for-mobile-push-notifications.md)。

 要使用 API 将推送通知消息发送到移动应用程序和设备，必须首先使用 `CreatePlatformApplication` 操作，它返回 `PlatformApplicationArn` 属性。然后 `PlatformApplicationArn` 使用 `CreatePlatformEndpoint` 属性，返回 `EndpointArn` 属性。之后，可以在 `EndpointArn` 操作中使用 `Publish` 属性将通知消息发送到移动应用程序和设备，也可以在 `EndpointArn` 操作中使用 `Subscribe` 属性订阅主题。有关更多信息，请参阅 [使用 Amazon SNS 设置推送通知](sns-mobile-application-as-subscriber.md#sns-user-notifications-process-overview)。

Amazon SNS 移动推送 API 如下：

`[CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)`  
为设备和移动应用程序可能注册的受支持推送通知服务（如 APNs 和 FCM）之一创建平台应用程序对象。返回 `PlatformApplicationArn` 操作所使用的 `CreatePlatformEndpoint` 属性。

`[CreatePlatformEndpoint](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html)`  
为受支持推送通知服务上的设备和移动应用程序创建终端节点。`CreatePlatformEndpoint` 使用从 `PlatformApplicationArn` 操作返回的 `CreatePlatformApplication` 属性。`EndpointArn` 属性是使用 `CreatePlatformEndpoint` 时返回的，它用在 `Publish` 操作中将通知消息发送到移动应用程序和设备。

`[CreateTopic](https://docs.aws.amazon.com/sns/latest/api/API_CreateTopic.html)`  
创建可以发布消息的主题。

`[DeleteEndpoint](https://docs.aws.amazon.com/sns/latest/api/API_DeleteEndpoint.html)`  
删除一个受支持推送通知服务上的设备和移动应用程序的终端节点。

`[DeletePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_DeletePlatformApplication.html)`  
删除平台应用程序数据元。

`[DeleteTopic](https://docs.aws.amazon.com/sns/latest/api/API_DeleteTopic.html)`  
删除主题及其所有订阅。

`[GetEndpointAttributes](https://docs.aws.amazon.com/sns/latest/api/API_GetEndpointAttributes.html)`  
检索设备和移动应用程序的终端节点属性。

`[GetPlatformApplicationAttributes](https://docs.aws.amazon.com/sns/latest/api/API_GetPlatformApplicationAttributes.html)`  
检索平台应用程序数据元的属性。

`[ListEndpointsByPlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_ListEndpointsByPlatformApplication.html)`  
列出受支持推送通知服务中的设备和移动应用程序的终端节点和终端节点属性。

`[ListPlatformApplications](https://docs.aws.amazon.com/sns/latest/api/API_ListPlatformApplications.html)`  
列出受支持推送通知服务的平台应用程序数据元。

`[Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)`  
向主题的所有订阅终端节点发送通知消息。

`[SetEndpointAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetEndpointAttributes.html)`  
设置设备和移动应用程序的终端节点属性。

`[SetPlatformApplicationAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetPlatformApplicationAttributes.html)`  
设置平台应用程序数据元的属性。

`[Subscribe](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html)`  
准备通过向终端节点发送确认消息来订阅终端节点。要实际创建订阅，终端节点所有者必须使用确认消息中的令牌调用 ConfirmSubscription 操作。

`[Unsubscribe](https://docs.aws.amazon.com/sns/latest/api/API_Unsubscribe.html)`  
删除订阅。

# Amazon SNS 移动推送 API 常见错误
<a name="mobile-push-api-error"></a>

下表列出了移动推送 Amazon SNS API 返回的错误。有关移动推送 Amazon SNS API 的更多信息，请参阅 [移动推送 API 操作](mobile-push-api.md)。


| 错误 | 描述 | HTTPS 状态代码 | API 操作 | 
| --- | --- | --- | --- | 
| Application Name is null string | 必需的应用程序名称设置为 Null。 | 400 | `CreatePlatformApplication` | 
| Platform Name is null string | 必需的平台名称设置为 Null。 | 400 | `CreatePlatformApplication` | 
| Platform Name is invalid | 为平台名称提供的值无效或超出范围。 | 400 | `CreatePlatformApplication` | 
| APNs — Principal is not a valid certificate | 为 APNs 主体（即 SSL 证书）提供了无效证书。有关更多信息，请参阅《Amazon Simple Notification Service API Reference》中的 [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)。 | 400 | `CreatePlatformApplication` | 
| APNs — Principal is a valid cert but not in a .pem format | 为 APNs 主体（即 SSL 证书）提供了非 .pem 格式的有效证书。 | 400 | `CreatePlatformApplication` | 
| APNs — Principal is an expired certificate | 为 APNs 主体（即 SSL 证书）提供了过期证书。 | 400 | `CreatePlatformApplication` | 
| APNs — Principal is not an Apple issued certificate | 为 APNs 主体（即 SSL 证书）提供了非 Apple 颁发的证书。 | 400 | `CreatePlatformApplication` | 
| APNs — Principal is not provided | 未提供 APNs 主体（即 SSL 证书）。 | 400 | `CreatePlatformApplication` | 
| APNs — Credential is not provided | 未提供 APNs 凭证（即私有密钥）。有关更多信息，请参阅《Amazon Simple Notification Service API Reference》中的 [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)。 | 400 | `CreatePlatformApplication` | 
| APNs — Credential are not in a valid .pem format | APNs 凭证（即私有密钥）不是有效的 .pem 格式。 | 400 | `CreatePlatformApplication` | 
| FCM — serverAPIKey is not provided | 未提供 FCM 凭证（即 API 密钥）。有关更多信息，请参阅《Amazon Simple Notification Service API Reference》中的 [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)。 | 400 | `CreatePlatformApplication` | 
| FCM — serverAPIKey is empty | FCM 凭证（即 API 密钥）为空。 | 400 | `CreatePlatformApplication` | 
| FCM — serverAPIKey is a null string | FCM 凭证（即 API 密钥）为 Null。 | 400 | `CreatePlatformApplication` | 
| FCM — serverAPIKey is invalid | FCM 凭证（即 API 密钥）无效。 | 400 | `CreatePlatformApplication` | 
| ADM — clientsecret is not provided | 未提供必需的客户端密钥。 | 400 | `CreatePlatformApplication` | 
| ADM — clientsecret is a null string | 客户端密钥所需的字符串为 Null。 | 400 | `CreatePlatformApplication` | 
| ADM — client\$1secret is empty string | 客户端密钥所需的字符串为空。 | 400 | `CreatePlatformApplication` | 
| ADM — client\$1secret is not valid | 客户端密钥所需的字符串无效。 | 400 | `CreatePlatformApplication` | 
| ADM — client\$1id is empty string | 客户端 ID 所需的字符串为空。 | 400 | `CreatePlatformApplication` | 
| ADM — clientId is not provided | 未提供客户端 ID 所需的字符串。 | 400 | `CreatePlatformApplication` | 
| ADM — clientid is a null string | 客户端 ID 所需的字符串为 Null。 | 400 | `CreatePlatformApplication` | 
| ADM — client\$1id is not valid | 客户端 ID 所需的字符串无效。 | 400 | `CreatePlatformApplication` | 
| EventEndpointCreated has invalid ARN format | EventEndpointCreated 具有无效 ARN 格式。 | 400 | `CreatePlatformApplication` | 
| EventEndpointDeleted has invalid ARN format | EventEndpointDeleted 具有无效 ARN 格式。 | 400 | `CreatePlatformApplication` | 
| EventEndpointUpdated has invalid ARN format | EventEndpointUpdated 具有无效 ARN 格式。 | 400 | `CreatePlatformApplication` | 
| EventDeliveryAttemptFailure has invalid ARN format | EventDeliveryAttemptFailure 具有无效 ARN 格式。 | 400 | `CreatePlatformApplication` | 
| EventDeliveryFailure has invalid ARN format | EventDeliveryFailure 具有无效 ARN 格式。 | 400 | `CreatePlatformApplication` | 
| EventEndpointCreated is not an existing Topic | EventEndpointCreated 不是现有主题。 | 400 | `CreatePlatformApplication` | 
| EventEndpointDeleted is not an existing Topic | EventEndpointDeleted 不是现有主题。 | 400 | `CreatePlatformApplication` | 
| EventEndpointUpdated is not an existing Topic | EventEndpointUpdated 不是现有主题。 | 400 | `CreatePlatformApplication` | 
| EventDeliveryAttemptFailure is not an existing Topic | EventDeliveryAttemptFailure 不是现有主题。 | 400 | `CreatePlatformApplication` | 
| EventDeliveryFailure is not an existing Topic | EventDeliveryFailure 不是现有主题。 | 400 | `CreatePlatformApplication` | 
| Platform ARN is invalid | 平台 ARN 无效。 | 400 | `SetPlatformAttributes` | 
| Platform ARN is valid but does not belong to the user | 平台 ARN 有效，但不属于该用户。 | 400 | `SetPlatformAttributes` | 
| APNs — Principal is not a valid certificate | 为 APNs 主体（即 SSL 证书）提供了无效证书。有关更多信息，请参阅《Amazon Simple Notification Service API Reference》中的 [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)。 | 400 | `SetPlatformAttributes` | 
| APNs — Principal is a valid cert but not in a .pem format | 为 APNs 主体（即 SSL 证书）提供了非 .pem 格式的有效证书。 | 400 | `SetPlatformAttributes` | 
| APNs — Principal is an expired certificate | 为 APNs 主体（即 SSL 证书）提供了过期证书。 | 400 | `SetPlatformAttributes` | 
| APNs — Principal is not an Apple issued certificate | 为 APNs 主体（即 SSL 证书）提供了非 Apple 颁发的证书。 | 400 | `SetPlatformAttributes` | 
| APNs — Principal is not provided | 未提供 APNs 主体（即 SSL 证书）。 | 400 | `SetPlatformAttributes` | 
| APNs — Credential is not provided | 未提供 APNs 凭证（即私有密钥）。有关更多信息，请参阅《Amazon Simple Notification Service API Reference》中的 [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)。 | 400 | `SetPlatformAttributes` | 
| APNs — Credential are not in a valid .pem format | APNs 凭证（即私有密钥）不是有效的 .pem 格式。 | 400 | `SetPlatformAttributes` | 
| FCM — serverAPIKey is not provided | 未提供 FCM 凭证（即 API 密钥）。有关更多信息，请参阅《Amazon Simple Notification Service API Reference》中的 [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)。 | 400 | `SetPlatformAttributes` | 
| FCM — serverAPIKey is a null string | FCM 凭证（即 API 密钥）为 Null。 | 400 | `SetPlatformAttributes` | 
| ADM — clientId is not provided | 未提供客户端 ID 所需的字符串。 | 400 | `SetPlatformAttributes` | 
| ADM — clientid is a null string | 客户端 ID 所需的字符串为 Null。 | 400 | `SetPlatformAttributes` | 
| ADM — clientsecret is not provided | 未提供必需的客户端密钥。 | 400 | `SetPlatformAttributes` | 
| ADM — clientsecret is a null string | 客户端密钥所需的字符串为 Null。 | 400 | `SetPlatformAttributes` | 
| EventEndpointUpdated has invalid ARN format | EventEndpointUpdated 具有无效 ARN 格式。 | 400 | `SetPlatformAttributes` | 
| EventEndpointDeleted has invalid ARN format | EventEndpointDeleted 具有无效 ARN 格式。 | 400 | `SetPlatformAttributes` | 
| EventEndpointUpdated has invalid ARN format | EventEndpointUpdated 具有无效 ARN 格式。 | 400 | `SetPlatformAttributes` | 
| EventDeliveryAttemptFailure has invalid ARN format | EventDeliveryAttemptFailure 具有无效 ARN 格式。 | 400 | `SetPlatformAttributes` | 
| EventDeliveryFailure has invalid ARN format | EventDeliveryFailure 具有无效 ARN 格式。 | 400 | `SetPlatformAttributes` | 
| EventEndpointCreated is not an existing Topic | EventEndpointCreated 不是现有主题。 | 400 | `SetPlatformAttributes` | 
| EventEndpointDeleted is not an existing Topic | EventEndpointDeleted 不是现有主题。 | 400 | `SetPlatformAttributes` | 
| EventEndpointUpdated is not an existing Topic | EventEndpointUpdated 不是现有主题。 | 400 | `SetPlatformAttributes` | 
| EventDeliveryAttemptFailure is not an existing Topic | EventDeliveryAttemptFailure 不是现有主题。 | 400 | `SetPlatformAttributes` | 
| EventDeliveryFailure is not an existing Topic | EventDeliveryFailure 不是现有主题。 | 400 | `SetPlatformAttributes` | 
| Platform ARN is invalid | 平台 ARN 无效。 | 400 | `GetPlatformApplicationAttributes` | 
| Platform ARN is valid but does not belong to the user | 平台 ARN 有效，但不属于该用户。 | 403 | `GetPlatformApplicationAttributes` | 
| Token specified is invalid | 指定的令牌无效。 | 400 | `ListPlatformApplications` | 
| Platform ARN is invalid | 平台 ARN 无效。 | 400 | `ListEndpointsByPlatformApplication` | 
| Platform ARN is valid but does not belong to the user | 平台 ARN 有效，但不属于该用户。 | 404 | `ListEndpointsByPlatformApplication` | 
| Token specified is invalid | 指定的令牌无效。 | 400 | `ListEndpointsByPlatformApplication` | 
| Platform ARN is invalid | 平台 ARN 无效。 | 400 | `DeletePlatformApplication` | 
| Platform ARN is valid but does not belong to the user | 平台 ARN 有效，但不属于该用户。 | 403 | `DeletePlatformApplication` | 
| Platform ARN is invalid | 平台 ARN 无效。 | 400 | `CreatePlatformEndpoint` | 
| Platform ARN is valid but does not belong to the user | 平台 ARN 有效，但不属于该用户。 | 404 | `CreatePlatformEndpoint` | 
| Token is not specified | 未指定令牌。 | 400 | `CreatePlatformEndpoint` | 
| Token is not of correct length | 令牌长度不正确。 | 400 | `CreatePlatformEndpoint` | 
| Customer User data is too large | 客户用户数据的长度不能超过 2048 个字节（UTF-8 编码）。 | 400 | `CreatePlatformEndpoint` | 
| Endpoint ARN is invalid | 端点 ARN 无效。 | 400 | `DeleteEndpoint` | 
| Endpoint ARN is valid but does not belong to the user | 端点 ARN 有效，但不属于该用户。 | 403 | `DeleteEndpoint` | 
| Endpoint ARN is invalid | 端点 ARN 无效。 | 400 | `SetEndpointAttributes` | 
| Endpoint ARN is valid but does not belong to the user | 端点 ARN 有效，但不属于该用户。 | 403 | `SetEndpointAttributes` | 
| Token is not specified | 未指定令牌。 | 400 | `SetEndpointAttributes` | 
| Token is not of correct length | 令牌长度不正确。 | 400 | `SetEndpointAttributes` | 
| Customer User data is too large | 客户用户数据的长度不能超过 2048 个字节（UTF-8 编码）。 | 400 | `SetEndpointAttributes` | 
| Endpoint ARN is invalid | 端点 ARN 无效。 | 400 | `GetEndpointAttributes` | 
| Endpoint ARN is valid but does not belong to the user | 端点 ARN 有效，但不属于该用户。 | 403 | `GetEndpointAttributes` | 
| Target ARN is invalid | 目标 ARN 无效。 | 400 | `Publish` | 
| Target ARN is valid but does not belong to the user | 目标 ARN 有效，但不属于该用户。 | 403 | `Publish` | 
| Message format is invalid | 消息格式无效。 | 400 | `Publish` | 
| Message size is larger than supported by protocol/end-service | 消息大小超过协议/端点服务支持的范围。 | 400 | `Publish` | 

# 使用移动推送通知的 Amazon SNS 生存时间消息属性
<a name="sns-ttl"></a>

Amazon Simple Notification Service (Amazon SNS) 支持设置移动推送通知消息的*生存时间 (TTL)* 消息属性。该功能不同于在移动推送通知服务的 Amazon SNS 消息正文中设置 TTL（如果该推送通知服务支持的话）的功能，如发送到 Android 时的 Amazon Device Messaging（ADM）和 Firebase Cloud Messaging（FCM）。

TTL 消息属性用于指定有关消息的过期元数据。这允许您指定推送通知服务（例如 Apple 推送通知服务 (APNs) 或 FCM）将消息传送到端点所需的时间。如果因为某种原因（如移动设备已关闭），消息无法在指定的 TTL 内传达，则系统将丢弃该消息，且不再尝试传送它。要在消息属性中指定 TTL，可以使用 AWS 管理控制台、 AWS 软件开发套件 (SDKs) 或查询 API。

## 推送通知服务的 TTL 消息属性
<a name="sns-ttl-msg-attrib"></a>

以下是推送通知服务的 TTL 消息属性列表，您可以使用这些属性在使用 AWS SDKs 或查询 API 时进行设置：


****  

| 推送通知服务 | TTL 消息属性 | 
| --- | --- | 
| Amazon Device Messaging（ADM） | AWS.SNS.MOBILE.ADM.TTL | 
| 苹果推送通知服务 (APNs) | AWS.SNS.MOBILE.APNS.TTL | 
| Apple 推送通知服务沙盒 (APNs\$1SANDBOX) | AWS.SNS.MOBILE.APNS\$1SANDBOX.TTL | 
| 百度云推送（百度） | AWS.SNS.MOBILE.BAIDU.TTL | 
| Firebase Cloud Messaging（FCM，发送到 Android 时） | AWS.SNS.MOBILE.FCM.TTL | 
| Windows 推送通知服务（WNS） | AWS.SNS.MOBILE.WNS.TTL | 

每个推送通知服务以不同的方式处理 TTL。Amazon SNS 提供了涵盖所有推送通知服务的 TTL 抽象视图，使您能够更方便地指定 TTL。当您使用指定 TTL（ AWS 管理控制台 以秒为单位）时，您只需输入一次 TTL 值，然后 Amazon SNS 将在发布消息时计算每种选定推送通知服务的 TTL。

 TTL 是相对于发布时间的。在将推送通知消息转交给特定的推送通知服务之前，Amazon SNS 会计算该推送通知的停留时间（发布时间戳与将消息转交给推送通知服务之间的时间差），并将剩余的 TTL 传递给特定的推送通知服务。如果 TTL 短于停留时间，Amazon SNS 不会尝试发布。

如果您为推送通知消息指定 TTL，则 TTL 值必须为正整数，除非的值对推送通知服务`0`有特定的含义，例如 with APNs 和 FCM（发送到 Android 时）。如果 TTL 值设为 `0`，但该推送通知服务对 `0` 无具体意义，则 Amazon SNS 将丢弃该消息。有关使用`0`时设置为的 TTL 参数的更多信息 APNs，请参阅 B [inary Provider API](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/BinaryProviderAPI.html) 文档中*远程通知的表 A-3 项目标识符*。

## 决定 TTL 的优先顺序
<a name="sns-ttl-precedence"></a>

Amazon SNS 根据以下顺序来决定推送通知消息的 TTL，数字越小，优先级越高：

1. 消息属性 TTL

1. 消息正文 TTL

1. 推送通知服务默认 TTL（随服务而变）

1. Amazon SNS 默认 TTL（4 周）

如果您为同一条消息设置了不同的 TTL 值（分别是消息属性和消息正文的 TTL），则 Amazon SNS 会修改消息正文中的 TTL，以匹配消息属性中指定的 TTL。

## 使用指定 TTL AWS 管理控制台
<a name="sns-ttl-console"></a>

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航面板中，选择**移动**，**推送通知**。

1. 在 **Mobile push notifications (移动推送通知)** 页面上的**平台应用程序**部分中，选择应用程序。

1. 在该***MyApplication***页面的**终端节点**部分，选择应用程序终端节点，然后选择**发布消息**。

1. 在**消息详细信息**部分中，输入 TTL（推送通知服务必须向终端节点发送消息的秒数）。

1. 选择**发布消息**。

# Amazon SNS 移动应用程序支持的区域
<a name="sns-mobile-push-supported-regions"></a>

目前，您可以在以下区域内创建移动应用程序：
+ 美国东部（俄亥俄州）
+ 美国东部（弗吉尼亚州北部）
+ 美国西部（北加利福尼亚）
+ 美国西部（俄勒冈州）
+ 非洲（开普敦）
+ 亚太地区（香港）
+ 亚太地区（雅加达）
+ 亚太地区（孟买）
+ 亚太地区（大阪）
+ 亚太地区（首尔）
+ 亚太地区（新加坡）
+ 亚太地区（悉尼）
+ 亚太地区（东京）
+ 加拿大（中部）
+ 欧洲地区（法兰克福）
+ 欧洲地区（爱尔兰）
+ 欧洲地区（伦敦）
+ 欧洲地区（米兰）
+ 欧洲（西班牙）
+ 欧洲地区（巴黎）
+ 欧洲地区（斯德哥尔摩）
+ 中东（巴林）
+ 中东（阿联酋）：
+ 南美洲（圣保罗）
+ AWS GovCloud （美国西部）

# 管理 Amazon SNS 移动推送通知的最佳实践
<a name="mobile-push-notifications-best-practices"></a>

本部分介绍可帮助您提升客户参与度的最佳实践。

## 终端节点管理
<a name="channels-sms-best-practices-endpoint-management"></a>

如果由于用户在设备上进行操作（例如，在设备上重新安装应用程序）导致设备令牌发生变化，或者[证书更新](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns)影响了在特定 iOS 版本上运行的设备，则可能导致传送过程出现问题。Apple 推荐的最佳做法是在 APNs 每次启动应用程序时进行[注册](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/HandlingRemoteNotifications.html#:~:text=Registering%20to%20Receive%20Remote%20Notifications)。

由于在用户每次打开应用时设备令牌不会发生变化，因此可以使用幂等 [https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html) API。但是，如果令牌本身无效，或者端点有效但已禁用（例如，生产环境和沙盒环境不匹配），则上述方法可能会为同一设备引入重复项。

可以使用设备令牌管理机制，例如[伪代码](mobile-platform-endpoint.md#mobile-platform-endpoint-pseudo-code)中的一种此类机制。

有关管理和维护 FCM v1 设备令牌的信息，请参阅 [Amazon SNS 管理 Firebase Cloud Messaging 端点](sns-fcm-endpoint-management.md)。

## 传送状态日志记录
<a name="channels-sms-best-practices-delivery-logging"></a>

要监控推送通知传送状态，我们建议您为 Amazon SNS 平台应用程序启用传送状态日志记录。这有助于您排查传送失败问题，因为日志包含从推送平台服务返回的提供商[响应代码](sns-msg-status.md#platform-returncodes)。有关启用传送状态日志记录的详细信息，请参阅[如何访问 Amazon SNS 主题的推送通知传送日志记录？](https://aws.amazon.com/premiumsupport/knowledge-center/troubleshoot-failed-sns-deliveries/)

## 事件通知
<a name="channels-sms-best-practices-event-notifications"></a>

要以事件驱动的方式管理终端节点，您可以利用[事件通知](application-event-notifications.md#application-event-notifications-sdk)功能。这样，已配置的 Amazon SNS 主题就可以针对终端节点创建、删除、更新和传送失败等平台应用程序事件，向订阅者（例如 Lambda 函数）发送事件。