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 для получения уведомлений.
Надеюсь, это кому-то поможет