Closed rootko closed 2 years ago
I've created a helper method that populates JSONObject with correct json format (as is expected from awsconfiguration.json) and use this object in AWSAppSyncClient.Builder like this:
AWSAppSyncClient.builder().awsConfiguration(new AWSConfiguration(buildJsonConfig()))
subscriptions are working again. So this workaround is working, it can be easily implemented to the official SDK.
I have the same problem. any Fix?
As mentioned above, you have to write your own wrapper that will populate theAWSConfiguration
:
client = AWSAppSyncClient.builder()
.context(context)
.credentialsProvider(credProvider)
.region(Regions.EU_WEST_1)
.serverUrl(Utils.getAppsyncApiUrl(env))
.persistentMutationsCallback(persistentCallback)
.s3ObjectManager(getS3ObjectManager(credProvider))
.subscriptionsAutoReconnect(true)
.okHttpClient(getOkHttpClient(context))
.subscriptionsAutoReconnect(true)
.awsConfiguration(new AWSConfiguration(buildJsonConfig(credProvider, region.getName(), identityId, env)))
.build();
I did a helper method like this:
private JSONObject buildJsonConfig(CognitoCachingCredentialsProvider credProvider, String region, String identityId, Utils.Env env) {
JSONObject jsonConfig = new JSONObject();
try {
jsonConfig.put("UserAgent", "aws-amplify-cli/0.1.0");
jsonConfig.put("Version", "1.0");
JSONObject identityManager = new JSONObject();
JSONObject identityManagerDefault = new JSONObject();
identityManager.put("Default", identityManagerDefault);
jsonConfig.put("IdentityManager", identityManager);
JSONObject appSync = new JSONObject();
JSONObject appSyncDefault = new JSONObject();
appSyncDefault.put("ApiUrl", Utils.getAppsyncApiUrl(env));
appSyncDefault.put("Region", region);
appSyncDefault.put("AuthMode", "AWS_IAM");
appSyncDefault.put("ClientDatabasePrefix", env);
appSync.put("Default", appSyncDefault);
jsonConfig.put("AppSync", appSync);
JSONObject cognitoUserPool = new JSONObject();
JSONObject cognitoUserPoolDefault = new JSONObject();
cognitoUserPoolDefault.put("PoolId", identityId);
cognitoUserPoolDefault.put("AppClientId", credProvider.getCredentials().getAWSAccessKeyId());
cognitoUserPoolDefault.put("AppClientSecret", credProvider.getCredentials().getAWSSecretKey());
cognitoUserPoolDefault.put("Region", region);
cognitoUserPool.put("Default", cognitoUserPoolDefault);
jsonConfig.put("CognitoUserPool", cognitoUserPool);
JSONObject credentialsProvider = new JSONObject();
JSONObject cognitoIdentity = new JSONObject();
JSONObject cognitoIdentityDefault = new JSONObject();
cognitoIdentityDefault.put("PoolId", Utils.getAppsyncDeveloperProviderIdentityPoolId(env));
cognitoIdentityDefault.put("Region", region);
cognitoIdentity.put("Default", cognitoIdentityDefault);
credentialsProvider.put("CognitoIdentity", cognitoIdentity);
jsonConfig.put("CredentialsProvider", credentialsProvider);
} catch (Exception e) {
Logger.e(e);
}
return jsonConfig;
}
Just be aware that credProvider.getCredentials().getAWSAccessKeyId()
is a network call, so you have to create AWSAppSyncClient
on background thread, otherwise you'll end up with an NetworkOnMainThreadException
.
The SubscriptionAuthorizer
(especially SubscriptionAuthorizer. getAuthorizationDetailsForIAM
) ignores fields set on the AppSyncClient builder almost entirely, and relies on the AWSConfiguration
information regardless of what has been set on the builder.
It also ignores any CredentialsProvider
given to the builder and uses its own CognitoCachingCredentialsProvider
-- which appears to be the reason this error is occurring in the first place. If it didn't ignore the credentials provider the Builder is given, we wouldn't need the PoolId
to create a CognitoCachingCredentialsProvider
... which (I don't believe) is required anyway -- it can use any AWSCredentialsProvider
, which means the PoolId
isn't needed.
I'm trying to create a PR to fix this issue, but I can't seem to include this project locally for some reason... has anyone been able to clone this and use a local version in their project?
@awslabs any idea if / when this is going to be fixed?
@jamesonwilliams @awslabs @rootko PR to fix this issue here: https://github.com/awslabs/aws-mobile-appsync-sdk-android/pull/276/files
@mslagle-gd a proper fix in the AWS library would be awesome, thanks for the PR ;)
Still doesn't work aws_appsync = '3.1.2'
Client.builder()
.context(applicationContext())
.cognitoUserPoolsAuthProvider(getUserPool())
.region(REGION)
.defaultResponseFetcher(NetworkOnlyFetcher())
.conflictResolver(ConflictResolver())
.serverUrl("url")
.okHttpClient(client)
.build()
When we can expect this will be fix? This prevents upgrading to 3.x.
Describe the bug Hi, in new Android version 3.0.x there's a new piece of code in
AWSAppSyncClient
constructor that expects that configuration is not filled programmatically viaAWSAppSyncClient.Builder
, but provided inawsconfiguration.json
file:Therefore each subscription fails, unless we provide aforementioned
awsconfiguration.json
file. Since we use more environments for various stages of deployment and tests, and the configuration is already provided via Builder, this is clearly an oversight. I'd expect a check forbuilder.mAwsConfiguration != null
and in case it's null, take the configuration from the builder instance instead.As a workaround I probably could use a constructor
public AWSConfiguration(JSONObject jsonObject)
to provide json file from Builder properties and use it to populatemAwsConfiguration
variable until this is solved.The AWSAppSyncClient constructor ends up with the exception:
To Reproduce Steps to reproduce the behavior:
awsconfiguration.json
file.Expected behavior Subscriptions should work without
awsconfiguration.json
, if the configuration is provided programmatically in Builder.Environment(please complete the following information):
Device Information (please complete the following information): Any and all devices
Additional context works with
'com.amazonaws:aws-android-sdk-appsync:2.10.1'