从Amazon SNS获取“EndpointDisabled”

我正在使用Amazon SNS。 通知工作正常,但有时我得到这个错误:

{ "message": "Endpoint is disabled", "code": "EndpointDisabled", "name": "EndpointDisabled", "statusCode": 400, "retryable": false } 

也许你知道为什么。

您可以创build一个新的SNS主题,例如push-notification-failures ,然后将APNS / APNS_SANDBOX应用程序的“Delivery Failures”事件关联到该主题。 通过电子邮件订阅活动(并确认),您将获得有关失败的有用debugging信息。 这可以通过SNS控制台完成,不需要API调用来执行。

为这个SNS主题订阅一个HTTP端点可能是值得的,并且logging所有的交付失败,所以你有历史数据来处理和debugging生产问题。

例如,“与端点关联的平台标记无效”的递送FailureMessage意味着您正在从APNS_SANDBOX向APNS注册的设备发送消息,反之亦然。 这可能意味着你的编译系统有错误的APNS设置。 (我们有一个令人沮丧的问题,开发人员构build的二进制文件使用APNS_SANDBOX与TestFlight构build的二进制文件使用APNS进行本地testing和QA,这导致我走上了这条道路。

到目前为止,我发现了三个原因:

  • 有时我们从沙盒应用程序中混入了令牌。
  • 用户在电话设置中closures通知。
  • 用户卸载了该应用程序。

这些是关于Iphons / Ipads。

根据http://docs.aws.amazon.com/sns/latest/APIReference/API_Publish.html ,这意味着端点被禁用。

http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/sns/model/SetEndpointAttributesRequest.html

启用 – 启用/禁用传递到端点的标志。 当通知服务向SNS指示端点无效时,消息处理器将把它设置为假。 用户可以将其设置回真,通常在更新令牌之后。

在这种情况下,“通知服务”是指Google的GCM,苹果APNS或亚马逊的ADM。

有几个原因可以禁用端点。 我没有看到它logging在任何地方(可能错过了),这是我从支持:

  • 您推送到端点,但令牌无效/过期。 在以下情况下令牌无效:

  • 它属于应用程序不再安装在设备上。

  • 如果设备已从备份中恢复。 这会使标记无效,您的应用程序应该请求一个新标记并相应地更新SNS端点标记。

  • 应用程序已被重新安装在同一个设备上。 在Android的情况下,应用程序被分配一个新的令牌。 对于APN,这种情况也是如此,但更多的情况是使用Android。

  • 在APN的情况下,在xCode中select错误的configuration文件。 在这种情况下,通知失败,设备在APN反馈后被禁用。

  • 如果错误地将IOS开发用于iOS开发应用程序,反之亦然。

  • 如果苹果出于任何原因使您的IOS推送证书无效或有人撤销itunes连接门户的推送证书。 设备被禁用之前需要几个小时。

  • 如果您更新Google开发人员控制台的API密钥,而不更新SNS中的平台应用程序凭据,则与GCM一样。

  • 您推送到APN设备端点,但由于过期的推送证书,应用程序已被禁用。

  • 您推送到GCM设备端点,但API密钥已在Google开发人员控制台中更新,但未相应地更新SNS平台应用程序凭据。

对于细节,我推荐这个优秀的文章解决我的问题

我遇到过同样的问题。 这就是我所做的:

  1. 从钥匙串访问导出完整的证书到.p12文件
  2. 将私钥从Keychange Access导出到* private.p12文件

  3. 使用openssl与下载的.cer文件(来自iOS Developer MemberCenter)创build一个公共的.pem证书

  4. 使用openssl和生成的* private.p12文件创build一个私有的.pem密钥文件

  5. 在AWS SNS中创build一个新的应用程序。 给它一个名字。 select苹果开发。
  6. 从Keychain Access中select带有.p12扩展名的完整证书,然后键入从Keychain Access导出时select的密码将公共CERTIFICATE.pem文件的内容复制到标记为“Certificate”的textarea,包括开始和结束行:

     -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- 
  7. 仅将私钥.pem文件的部分以下面的行开头和结尾复制到标记为“Private Key”的textarea:

     -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- 

我使用Cordova和Phonegap-plugin-push 1.4.4,但是我的问题与phonecap无关。 除了上面的一些混淆之外,最后我做了什么,是在XCode中打开我的项目,find我的项目的目标,然后启用推送通知。 这会自动将“推送通知”权限添加到应用程序ID中。下次在您的设备上安装应用程序时,推送通知应该可以正常工作。 至less它为我做了。

我希望这可以为遇到与我同样的问题的人一个半天的工作! 🙂

采取严厉措施之前的快速清单:

  1. 使用钥匙串应用程序生成证书签名请求(CSR)。
  2. 使用Keychain App将APNS证书及其私钥导出到单个p12文件中。
  3. 在Amazon SNS中创build新应用程序时,平台必须与APNS环境(双方的开发 / 生产 )相匹配。
  4. 当您请求设备令牌时,您必须位于正确的应用程序中 (应用程序的包标识符与APNS证书相匹配)。
  5. 在AWS SNS中创build新的平台端点时,必须将设备令牌添加到正确的应用程序 (良好的应用程序证书和良好的开发/生产平台)。

在我的情况下,我使用第三方SSL工具生成CSR。 我从苹果开发者门户网站获得了有效的证书,但没有私钥。 然后,我试图Windows的证书工具导出没有很大的成功。 浪费时间。 启动你的Mac。

然后,我使用AmazonMobilePush示例应用程序获取设备标记。 由于演示版本的包标识符与我的证书不匹配,所以端点无效。 在每个SNS发送的端点被禁用(false)。 最后的原因很明显,但我仍然失去了宝贵的时间。

如果您收到错误“ End Point is Disabled ,请使用以下代码启用终点,然后使用Amazon凭据推送通知:

 *//Enable Device* var sns = new AmazonSimpleNotificationServiceClient("AwsAccesskeyId", "AwsSecrteAccessKey", RegionEndpoint.USWest1); Dictionary<string, string> objDictCheckEndpointEnable = new Dictionary<string, string>(); objDictCheckEndpointEnable.Add("Enabled", "False"); sns.SetEndpointAttributes(new SetEndpointAttributesRequest { Attributes = objDictCheckEndpointEnable, EndpointArn = "AwsEndPointArn" //This is Device End Point Arn }); *//End* 

对于我来说,由于我的SNS平台应用程序端点设置不正确,我得到了“与端点相关的平台标记无效”。 具体而言,即使SNS控制台包含正确的证书和专用密钥,但仍未从我的.p12文件正确读取凭证。 基于这篇文章的解决scheme是创build第二个包含cert和no键的.p12文件。 我从第一个.p12文件加载凭据,然后加载第二个.p12文件的凭据。 当我这样做的时候,我可以看到证书string发生了变化,之后我没有任何问题。

如果你正在创build一个生产端点,SNS会警告你关于不匹配的证书,但是它没有检查开发端点。 只有当您知道该端点是borked时,才会收到平台标记错误。

我当然希望这能帮助那里的人,因为它驱使我分心。

我正在使用这个。 如果get端点响应findNotFound错误,它会创build一个端点(这绝不会发生,但是它会在AWS SNS文档网站上)。 如果这没有发生,这意味着您正在获取端点的信息。 它可以是好的(令牌匹配和启用是正确的),或者反过来(在这种情况下,你需要更新它)。

  - (void)getEndpointDetailsWithResponse:(void(^)(AWSSNSGetEndpointAttributesResponse *response, AWSTask *))handleResponse { NSString * deviceTokenForAWS = [self deviceTokenForAWS]; AWSSNS *manager = [AWSSNS SNSForKey:@"EUWest1SNS"]; AWSSNSGetEndpointAttributesInput *input = [AWSSNSGetEndpointAttributesInput new]; input.endpointArn = self.endpointArn; AWSTask *getEndpointAttributesTask = [manager getEndpointAttributes:input]; [getEndpointAttributesTask continueWithBlock:^id(AWSTask *task) { NSLog(@"%@ Error: %@", task.result, task.error); AWSSNSGetEndpointAttributesResponse *result = task.result; NSError *error = task.error; if (error.code == AWSSNSErrorNotFound) { [self createEndpointWithResponse:^(AWSSNSCreateEndpointResponse *createResponse) { dispatch_async(dispatch_get_main_queue(), ^{ if (handleResponse != nil) { handleResponse(result, task); } }); }]; } else { NSLog(@"response for get endpoint attributes : %@", result); NSString *token = [result.attributes valueForKey:@"Token"]; NSString *enabled = [result.attributes valueForKey:@"Enabled"]; NSLog(@"token : %@, enabled : %@", token, enabled); BOOL wasSuccessful = [token isEqualToString:deviceTokenForAWS] && ([enabled localizedCaseInsensitiveCompare:@"true"] == NSOrderedSame); if (!wasSuccessful) { NSLog(@"device token does not match the AWS token OR it is disabled!"); NSLog(@"Need to update the endpoint"); AWSSNSSetEndpointAttributesInput *seai = [AWSSNSSetEndpointAttributesInput new]; seai.endpointArn = self.endpointArn; NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:deviceTokenForAWS, @"Token", @"true", @"Enabled", nil]; seai.attributes = attributes; AWSTask *setEndpointAttributesTask = [manager setEndpointAttributes:seai]; [setEndpointAttributesTask continueWithBlock:^id(AWSTask *task) { NSLog(@"response : %@, error: %@", task.result, task.error); dispatch_async(dispatch_get_main_queue(), ^{ if (handleResponse != nil) { handleResponse(result, task); } }); return nil; }]; } else { NSLog(@"all is good with the endpoint"); dispatch_async(dispatch_get_main_queue(), ^{ if (handleResponse != nil) { handleResponse(result, task); } }); } } return nil; }]; } 

这是AWS SNS令牌pipe理文档的精确副本: https : //mobile.awsblog.com/post/Tx223MJB0XKV9RU/Mobile-token-management-with-Amazon-SNS

如果需要的话,我可以附加其余的实现,但是这个部分是最重要的。

Interesting Posts