aws-amplify / aws-sdk-android

AWS SDK for Android. For more information, see our web site:
https://docs.amplify.aws
Other
1.02k stars 548 forks source link

You must be signed-in with Cognito Userpools to be able to use getTokens #3558

Closed Andrew0000 closed 3 months ago

Andrew0000 commented 3 months ago

State your question I try to get tokens via AWSMobileClient.getInstance().tokens and the SDK throws the error You must be signed-in with Cognito Userpools to be able to use getTokens. The user has a userpool and it's not clear what to do.

Which AWS Services are you utilizing? AWS Cognito + com.amazonaws:aws-android-sdk-mobile-client:2.73.0

Provide code snippets (if applicable) val tokens = AWSMobileClient.getInstance().tokens

Stacktrace:

java.lang.Exception: You must be signed-in with Cognito Userpools to be able to use getTokens
       at com.amazonaws.mobile.client.AWSMobileClient$12.run(AWSMobileClient.java:2017)
       at com.amazonaws.mobile.client.internal.InternalCallback.await(InternalCallback.java:115)
       at com.amazonaws.mobile.client.AWSMobileClient.getTokens(AWSMobileClient.java:1977)

Environment(please complete the following information):

Device Information (please complete the following information):

Additional details:

Previously I was able to get tokens via:

Amplify.Auth.plugins.filterIsInstance<AWSCognitoAuthPlugin>()
  .first()
  .let { plugin ->
    val tokens = plugin.escapeHatch.tokens
    //...
  }

but there is no more such functionality in the latest versions.

Andrew0000 commented 3 months ago

awsconfiguration.json probably contains redundant elements, I was experimenting trying to solve the error. Because there is no clear way to get a valid awsconfiguration.json from AWS, which is also a point to improve (or please tell me if the way exists)

Here the word exists means the value is masked:

{
  "UserAgent": "aws-amplify-cli/2.0",
  "Version": "1.0",
  "IdentityManager": {
    "Default": {}
  },
  "CredentialsProvider": {
    "CognitoIdentity": {
      "Default": {
        "PoolId": "exists",
        "AppClientId": "exists",
        "AppId": "exists",
        "Region": "exists"
      }
    }
  },
  "CognitoUserPool": {
    "Default": {
      "PoolId": "exists",
      "AppClientId": "exists",
      "AppId": "exists",
      "Region": "exists"
    }
  },
  "PinpointAnalytics": {
    "PoolId": "exists",
    "AppClientId": "exists",
    "AppId": "exists",
    "Region": "exists"
  }
}
tylerjroach commented 3 months ago

"but there is no more such functionality in the latest versions."

@Andrew0000 Can you clarify what version of Amplify you are using? The above statement gives me the impression you may have updated to Amplify v2.

Amplify v2 and AWS Android SDK are not compatible with each other. See this guide on compatibility. https://docs.amplify.aws/android/sdk/configuration/amplify-compatibility/

tylerjroach commented 3 months ago

To answer your other question about awsconfiguration.json, the Amplify CLI still creates this file, alongside amplifyconfiguration.json.

Andrew0000 commented 3 months ago

"but there is no more such functionality in the latest versions."

@Andrew0000 Can you clarify what version of Amplify you are using? The above statement gives me the impression you may have updated to Amplify v2.

Amplify v2 and AWS Android SDK are not compatible with each other. See this guide on compatibility. https://docs.amplify.aws/android/sdk/configuration/amplify-compatibility/

The code I provided worked on 1.x.x I migrated to 2.x.x It doesn't work. So I try to find how to solve my need (get access and id tokens). Just a real life case.

To answer your other question about awsconfiguration.json, the Amplify CLI still creates this file, alongside amplifyconfiguration.json.

It's absolutely inconvenient (and causes questions) to use CLI for such a basic thing like the android library setup.

tylerjroach commented 3 months ago

@Andrew0000 I'm not currently sure what your usage, but it is likely that you can entirely remove the AWS Android SDK and use Amplify only.

Amplify can get tokens by calling:

Amplify.Auth.fetchAuthSession(
    {
        val awsSession = it as AWSCognitoAuthSession
        val userPoolToken = awsSession.userPoolTokensResult.value?.idToken
        awsSession.awsCredentialsResult.value?.let { awsCredentials ->
            awsCredentials.accessKeyId
            awsCredentials.secretAccessKey
        }
        val identityId = awsSession.identityIdResult.value
    },
    {}
)

See here for more info: https://docs.amplify.aws/android/build-a-backend/auth/accessing-credentials/

Andrew0000 commented 3 months ago

Thank you, this looks like a possible solution. I'll try this migration.

Andrew0000 commented 3 months ago

@tylerjroach By the way, Amplify.Auth.fetchAuthSession seem asynchronous. Is there a way to just get tokens synchronously like it was earlier? The motivation is to eliminate a possible additional delay.

tylerjroach commented 3 months ago

I'm not sure if there is a use case where you would want expired tokens, but this is the reason that fetchAuthSession is async.

If you want to use these values synchronously, you can always grab the tokens and then cache them to be used synchronously instead.

You can also look into using our Kotlin Coroutines support which would help you write async code in a cleaner way. https://docs.amplify.aws/android/start/project-setup/kotlin-coroutines/