web-dev-qa-db-ja.com

Amazon SNSから「EndpointDisabled」を取得する

Amazon SNSを使用しています。通知はうまくいきますが、時々このエラーが表示されます:

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

たぶん、あなたはその理由を知っています。

53
user2881338

Push-notification-failuresなどの新しいSNSトピックを作成し、APNS/APNS_SANDBOXアプリケーションの「配信エラー」イベントをそれに関連付けることができます。電子メールを介してイベントにサブスクライブ(および確認)すると、障害に関する有用なデバッグ情報が得られます。これはすべてSNSコンソールから実行でき、API呼び出しを実行する必要はありません。

HTTPエンドポイントをこのSNSトピックにサブスクライブし、すべての配信エラーを記録して、運用上の問題を処理およびデバッグするための履歴データを取得することはおそらく価値があります。

たとえば、「エンドポイントに関連付けられたプラットフォームトークンが無効です」という配信FailureMessageは、APNS_SANDBOXからAPNS登録済みデバイスへ、またはその逆にメッセージを送信していることを意味します。これは、ビルドシステムのAPNS設定が間違っていることを意味します。 (開発者がAPNS_SANDBOXを使用してバイナリをビルドした場合と、テストおよびQAを使用してローカルテストとQAを使用してTestFlightがビルドした場合のイライラする問題があります。

69
cfeduke

私はこれまでに3つの理由を見つけました:

  • 時々、サンドボックスアプリからトークンを混合しました。
  • ユーザーは電話設定で通知をオフにします。
  • ユーザーがアプリをアンインストールしました。

これらはIphon/Ipadに関するものです。

37

エンドポイントを無効にできる理由はほとんどありません。私はそれがどこにも文書化されていなかった(それを見逃したかもしれない)、これは私がサポートから得たものです:

  • エンドポイントにプッシュしましたが、トークンが無効/期限切れです。次の場合、トークンは無効になります。

  • これは、デバイスにインストールされなくなったアプリに属します。

  • デバイスがバックアップから復元された場合。これによりトークンが無効になり、アプリは新しいトークンを要求し、それに応じてSNSエンドポイントトークンを更新する必要があります。

  • アプリは同じデバイスに再インストールされました。 Androidの場合、アプリには新しいトークンが割り当てられます。これはAPNでも起こりますが、Androidではより頻繁に起こります。

  • APNの場合、xCodeで間違ったプロビジョニングプロファイルが選択されます。この場合、通知は失敗し、APNのフィードバック後にデバイスが無効になります。

  • 誤ってトークンを使用してIOS開発からIOS本番アプリへ、またはその逆)。

  • Apple何らかの理由であなたのIOSプッシュ証明書または誰かがiTunes接続ポータルからプッシュ証明書を取り消します。デバイスが無効になるまでに数時間かかります。

  • SNSのプラットフォームアプリケーションの資格情報を更新せずにGoogle開発者コンソールからAPIキーを更新する場合、GCMと同じです。

  • APNsデバイスエンドポイントにプッシュしますが、プッシュ証明書の有効期限が切れたため、アプリケーションが無効になっています。

  • GCMデバイスエンドポイントにプッシュしますが、Google開発者コンソールでAPIキーが更新されていますが、それに応じてSNSプラットフォームアプリケーションの資格情報は更新されていません。

詳細については、この優れた article をお勧めします。これで問題が解決します

20
Farhan

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に示すと、メッセージプロセッサはこれをfalseに設定します。通常、トークンを更新した後、ユーザーはtrueに戻すことができます。

この場合の「通知サービス」とは、GoogleのGCM、Apples APNS、またはAmazonのADMを指します。

16
tster

同じ問題がありました。これは私がやったことです:

  1. キーチェーンアクセスから完全な証明書を.p12ファイルにエクスポートする
  2. keychange Accessから* private.p12ファイルにプライベートキーをエクスポートします

  3. ダウンロードした.cerファイル(iOS Developer MemberCenterから)でopensslを使用して、パブリック.pem証明書を作成します

  4. 生成された* private.p12ファイルでopensslを使用して、プライベート.pemキーファイルを作成します

  5. AWS SNSで新しいアプリケーションを作成します。名前を付けてください。 Apple Development。
  6. 拡張子が.p12のキーチェーンアクセスからFULL CERTIFICATEを選択し、キーチェーンアクセスからエクスポートするときに選択したパスフレーズを入力します。 :

    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----
    
  7. プライベートキーの.pemファイルの次の行で開始および終了する部分のみを、「プライベートキー」というラベルの付いたテキスト領域にコピーします。

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

Phonegap-plugin-Push 1.4.4でCordovaを使用していますが、私の問題はphonecapとは何の関係もありませんでした。上記に関する少しの混乱は別として、最終的に私にとってのトリックは、XCodeでプロジェクトを開き、プロジェクトのターゲットを見つけて、プッシュ通知を有効にすることでした。これにより、アプリIDに「プッシュ通知」資格が自動的に追加されます。次回アプリがデバイスにインストールされたときに、プッシュ通知が機能するはずです。少なくとも私にとってはそうでした。

これにより、私と同じ問題を経験している人が1日半の仕事で救われることを願っています! :)

5
luposlip

抜本的な対策を講じる前のクイックチェックリスト:

  1. Keychain Appを使用して証明書署名要求(CSR)を生成します。
  2. Keychain Appを使用して、APNS証明書とその秘密鍵を単一のp12ファイルにエクスポートします。
  3. Amazon SNSで新しいアプリケーションを作成する場合、プラットフォームはAPNS環境に一致する必要があります(両側で-Development/-Production)。
  4. デバイストークンを要求するときは、正しいアプリケーションにいる必要があります(アプリケーションのバンドル識別子はAPNS証明書と一致します)。
  5. AWS SNSで新しいプラットフォームエンドポイントを作成するとき、デバイストークンを正しいアプリケーション(良いアプリケーション証明書と良い開発/生産プラットフォーム)に追加する必要があります。

私の場合、サードパーティのSSLツールを使用してCSRを生成しました。有効な証明書をApple開発者ポータルから取得しましたが、秘密鍵は使用しませんでした。その後、Windowsの証明書ツールを試してみました。

次に、AmazonMobilePushサンプルアプリを使用してデバイストークンを取得しました。デモのバンドル識別子が証明書と一致しないため、エンドポイントは無効でした。エンドポイントを送信する各SNSで無効になりました(false)。最後に原因は明らかでしたが、私はまだ貴重な時間を失います。

4
rjobidon

これを使用しています。エンドポイントの取得応答でNotFoundエラーが検出されると、エンドポイントが作成されます(これは決して発生しないはずですが、AWS SNSドキュメントWebサイトにあります)。そうでない場合は、エンドポイントの情報を取得していることを意味します。それは大丈夫(トークンが一致し、有効になっている)か、または他の方法(この場合は更新する必要があります)のいずれかです。

    - (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トークン管理ドキュメントの正確なレプリカです。 https://mobile.awsblog.com/post/Tx223MJB0XKV9RU/Mobile-token-management-with-Amazon-SNS

必要に応じて残りの実装を添付できますが、この部分が最も重要です。

1
Danut Pralea

エラーが発生した場合はEnd Point is Disabled、以下のコードを使用して、endPointを有効にしてから、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*
1
Sanjay Dwivedi

私の場合、SNSプラットフォームアプリケーションエンドポイントが正しくセットアップされていなかったため、「エンドポイントに関連付けられたプラットフォームトークンが無効です」というメッセージが表示されました。具体的には、SNSコンソールに正しい証明書と秘密キーが含まれていても、.p12ファイルから資格情報を正しく読み取っていませんでした。 this post に基づく解決策は、証明書を含みキーを含まない2つ目の.p12ファイルを作成することでした。最初の.p12ファイルから資格情報をロードしてから、2番目の.p12ファイルの資格情報をロードしました。変更したときに証明書の文字列が変更されるのを見ることができ、その後は問題ありませんでした。

実稼働エンドポイントを作成している場合、SNSは不一致の証明書について警告しますが、開発エンドポイントのそのようなチェックは行いません。エンドポイントが停止していることを知る唯一の方法は、プラットフォームトークンエラーが発生したときです。

気晴らしに駆り立てられたので、これが誰かの助けになることを願っています。

1
phatmann