设置用于移动通知的 Amazon SNS 平台终端节点 - Amazon Simple Notification Service

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

设置用于移动通知的 Amazon SNS 平台终端节点

注册应用程序和移动设备的推送通知服务时,推送通知服务会返回设备令牌。Amazon SNS 使用设备令牌创建移动终端节点,它可以向该终端节点发送直接推送通知消息。有关更多信息,请参阅Amazon SNS 用户通知的先决条件使用 Amazon 设置推送通知 SNS

此部分介绍了创建平台终端节点的推荐方法。

创建平台终端节点

要通过亚马逊向应用程序推送通知SNS,必须先SNS通过调用创建平台终端节点操作向亚马逊注册该应用程序的设备令牌。此操作将平台应用程序的 Amazon 资源名称 (ARN) 和设备令牌作为参数,并返回已创建ARN的平台终端节点的。

CreatePlatformEndpoint操作执行以下操作:

  • 如果平台终端节点已经存在,请不要再次创建。将现有平台终端节点ARN的信息返回给调用者。

  • 如果已经存在具有相同设备令牌但设置不同的平台终端节点,请不要再次创建。向调用方引发异常。

  • 如果平台终端节点不存在,请创建它。向调用者返回新创建ARN的平台端点的值。

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

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

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

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

伪代码

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

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但它已被删除,就会发生这种情况。

  • 即使平台终端节点刚刚创建,也会调用该GetEndpointAttributes操作来验证平台终端节点的状态。平台终端节点已存在但被禁用时会出现这种情况。在这种情况下,创建平台终端节点操作成功,但不启用平台终端节点,因此您必须在返回成功之前仔细检查平台终端节点的状态。

AWS SDK示例

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

要使用 AWS SDK,必须使用您的凭据对其进行配置。有关更多信息,请参阅工具参考指南中的共享配置AWS SDKs和凭据文件

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
SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

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操作

故障排除

使用过期设备令牌重复调用创建平台终端节点操作

特别是对于FCM端点,您可能会认为最好存储应用程序发布的第一个设备令牌,然后在每次应用程序启动时使用该设备令牌调用创建平台端点。这似乎是正确的,因为它使应用程序不必管理设备令牌的状态,而且 Amazon SNS 会自动将设备令牌更新为其最新值。但是,此解决方案存在多个严重问题:

  • Amazon SNS 依靠来自的反馈FCM将过期的设备令牌更新为新的设备令牌。FCM将有关旧设备令牌的信息保留一段时间,但不能无限期保留。一旦FCM忘记了旧设备令牌和新设备令牌之间的连接,Amazon SNS 将无法再将存储在平台终端节点中的设备令牌更新为正确值;它只会禁用平台终端节点。

  • 平台应用程序将包含与同一个设备令牌对应的多个平台终端节点。

  • Amazon SNS 对可以从同一个设备令牌开始创建的平台终端节点数量设定配额。最终,新终端节点的创建将会失败,引发无效参数异常并显示以下错误消息:“此终端节点已注册到其他令牌。”

有关管理FCM终端节点的更多信息,请参阅亚马逊SNS管理 Firebase 云消息终端节点

重新启用与无效设备令牌关联的平台终端节点

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

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

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