InvalidConfigurationException: пул идентификаторов не настроен для SNS с помощью службы AmazonCognitoSync

Я пытался использовать AWS SDK для push-уведомлений. Но я получаю ошибки. Пытался найти решение, но не нашел поддержки.

iOS и веб-push-уведомления работают нормально

Что все уже настроено и сделано:

  • Настройка серверной части и консоли AWS на месте.
  • Идентификатор пула удостоверений и другие ключи на месте.
  • Тема ARN на месте.

Сторона Android:

  • Зависимости AWS SDK:

    implementation 'com.amazonaws:aws-android-sdk-core:2.16.8'
    implementation 'com.amazonaws:aws-android-sdk-cognito:2.6.23'
    implementation 'com.amazonaws:aws-android-sdk-s3:2.15.1'
    implementation 'com.amazonaws:aws-android-sdk-ddb:2.2.0'
    implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.16.8') { transitive = true; }
    

minSdk Версия 21

targetSdkVersion 29

  • Внутри onCreate:

    CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
                    getApplicationContext(),
                    "My Pool Id here", // Identity pool ID
                    Regions.US_EAST_1 // Region
            );
    
    CognitoSyncManager client = new CognitoSyncManager(
                            LoginActivateActivity.this,
                            Regions.US_EAST_1,
                            credentialsProvider);
    
                String registrationId = "MY_FCM_DEVICE_TOKEN"; **Instead of GCM ID, I am passing my unique FCM device token here. I searched, & it seems that wherever GCM is required, it is being replaced by FCM.**
                try {
                    client.registerDevice("GCM", registrationId);
                } catch (RegistrationFailedException rfe) {
                    Log.e("TAG", "Failed to register device for silent sync", rfe);
                } catch (AmazonClientException ace) {
                    Log.e("TAG", "An unknown error caused registration for silent sync to fail", ace);
                }
    
                Dataset trackedDataset = client.openOrCreateDataset("My Topic here");
                if (client.isDeviceRegistered()) {
                    try {
                        trackedDataset.subscribe();
                    } catch (SubscribeFailedException sfe) {
                        Log.e("TAG", "Failed to subscribe to datasets", sfe);
                    } catch (AmazonClientException ace) {
                        Log.e("TAG", "An unknown error caused the subscription to fail", ace);
                    }
                }
    

Я получаю ошибку на client.registerDevice("GCM", registrationId);

Вызвано: com.amazonaws.services.cognitosync.model.InvalidConfigurationException: пул идентификаторов не настроен для SNS (служба: AmazonCognitoSync; код состояния: 400; код ошибки: InvalidConfigurationException; идентификатор запроса: a858aaa2-**************************)

Заметка:

Я пробовал использовать библиотеки Amplify, но даже это не сработало. Кроме того, на iOS и в Интернете они используют AWS SDK. Так что я тоже буду использовать то же самое. Это даже не ошибка конкретного устройства.

Все, что мне нужно сделать, это настроить мой проект на получение push-уведомлений. Но я застрял на начальном этапе. Не удалось создать конечную точку для устройства Android.

1 ответ

Решение

Я действительно нашел решение проблемы благодаря другу, который поделился этой ссылкой:

https://aws.amazon.com/premiumsupport/knowledge-center/create-android-push-messaging-sns/

Это видео на Youtube также очень помогло:

https://www.youtube.com/watch?v=9QSO3ghSUNk&list=WL&index=3

Отредактированный код

private void registerWithSNS() {

        CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
                getApplicationContext(),
                "Your Identity Pool ID",
                Regions.US_EAST_1 // Region
        );

        client = new AmazonSNSClient(credentialsProvider);

        String endpointArn = retrieveEndpointArn();
        String token = "Your FCM Registration ID generated for the device";

        boolean updateNeeded = false;
        boolean createNeeded = (null == endpointArn || "".equalsIgnoreCase(endpointArn));

        if (createNeeded) {
            // No platform endpoint ARN is stored; need to call createEndpoint.
            endpointArn = createEndpoint(token);
            createNeeded = false;
        }

        System.out.println("Retrieving platform endpoint data...");
        // Look up the platform endpoint and make sure the data in it is current, even if
        // it was just created.
        try {
            GetEndpointAttributesRequest geaReq =
                    new GetEndpointAttributesRequest()
                            .withEndpointArn(endpointArn);
            GetEndpointAttributesResult geaRes =
                    client.getEndpointAttributes(geaReq);

            updateNeeded = !geaRes.getAttributes().get("Token").equals(token)
                    || !geaRes.getAttributes().get("Enabled").equalsIgnoreCase("true");

        } catch (NotFoundException nfe) {
            // We had a stored ARN, but the platform endpoint associated with it
            // disappeared. Recreate it.
            createNeeded = true;
        } catch (AmazonClientException e) {
            createNeeded = true;
        }

        if (createNeeded) {
            createEndpoint(token);
        }

        System.out.println("updateNeeded = " + updateNeeded);

        if (updateNeeded) {
            // The platform endpoint is out of sync with the current data;
            // update the token and enable it.
            System.out.println("Updating platform endpoint " + endpointArn);
            Map attribs = new HashMap();
            attribs.put("Token", token);
            attribs.put("Enabled", "true");
            SetEndpointAttributesRequest saeReq =
                    new SetEndpointAttributesRequest()
                            .withEndpointArn(endpointArn)
                            .withAttributes(attribs);
            client.setEndpointAttributes(saeReq);
        }
    }

    /**
     * @return never null
     * */
    private String createEndpoint(String token) {

        String endpointArn = null;
        try {
            System.out.println("Creating platform endpoint with token " + token);
            CreatePlatformEndpointRequest cpeReq =
                    new CreatePlatformEndpointRequest()
                            .withPlatformApplicationArn("Your Platform ARN. This you get from AWS Console. Unique for all devices for a platform.")
                            .withToken(token);
            CreatePlatformEndpointResult cpeRes = client
                    .createPlatformEndpoint(cpeReq);
            endpointArn = cpeRes.getEndpointArn();
        } catch (InvalidParameterException ipe) {
            String message = ipe.getErrorMessage();
            System.out.println("Exception message: " + message);
            Pattern p = Pattern
                    .compile(".*Endpoint (arn:aws:sns[^ ]+) already exists " +
                            "with the same [Tt]oken.*");
            Matcher m = p.matcher(message);
            if (m.matches()) {
                // The platform endpoint already exists for this token, but with
                // additional custom data that
                // createEndpoint doesn't want to overwrite. Just use the
                // existing platform endpoint.
                endpointArn = m.group(1);
            } else {
                // Rethrow the exception, the input is actually bad.
                throw ipe;
            }
        }
        storeEndpointArn(endpointArn);
        return endpointArn;
    }

    /**
     * @return the ARN the app was registered under previously, or null if no
     *         platform endpoint ARN is stored.
     */
    private String retrieveEndpointArn() {
        // Retrieve the platform endpoint ARN from permanent storage,
        // or return null if null is stored.
        return endpointArn;
    }

    /**
     * Stores the platform endpoint ARN in permanent storage for lookup next time.
     * */
    private void storeEndpointArn(String endpointArn) {
        // Write the platform endpoint ARN to permanent storage.
        UserSession.getSession(LoginActivateActivity.this).setARN(endpointArn); //Your platform endpoint ARN. This is unique for each device, but changes when 
    }

После создания конечной точки для устройства вам необходимо сохранить регистрационный идентификатор endpointArn и FCM в вашей БД на стороне сервера. Остальная часть кода будет вашим кодом реализации FCM для получения уведомлений.

Надеюсь, это кому-то поможет

Другие вопросы по тегам