aws-mobile-appsync-sdk-android icon indicating copy to clipboard operation
aws-mobile-appsync-sdk-android copied to clipboard

Cognito Userpools failed to get session

Open zhangjiancheng opened this issue 3 years ago • 22 comments

Describe the bug Friday opened the app and it runned in background thread, when Monday I make the app in front, the error occuces.

Environment(please complete the following information):

  • AppSync SDK Version: 3.1.1

Device Information (please complete the following information):

  • Device: HuaWei P30
  • Android Version: Android 10 (EMUI 11.0.0)

Additional context

2021-02-01 10:16:42.186 13424-29995/? E/AndroidRuntime: FATAL EXCEPTION: Thread-237
    Process: PACKAGENAME, PID: 13424
    java.lang.RuntimeException: Cognito Userpools failed to get session
        at com.amazonaws.mobileconnectors.appsync.sigv4.BasicCognitoUserPoolsAuthProvider.fetchToken(BasicCognitoUserPoolsAuthProvider.java:80)
        at com.amazonaws.mobileconnectors.appsync.sigv4.BasicCognitoUserPoolsAuthProvider.getLatestAuthToken(BasicCognitoUserPoolsAuthProvider.java:86)
        at PACKAGENAME.common.aws.AWSClientFactory$1.getLatestAuthToken(AWSClientFactory.java:37)
        at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getAuthorizationDetailsForUserpools(SubscriptionAuthorizer.java:160)
        at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getAuthorizationDetails(SubscriptionAuthorizer.java:85)
        at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.requestSubscription(WebSocketConnectionManager.java:92)
        at com.amazonaws.mobileconnectors.appsync.AppSyncWebSocketSubscriptionCall.execute(AppSyncWebSocketSubscriptionCall.java:48)
        at PACKAGENAME.activities.chat.RoomMessageView.prepareOnUpdateRoomLastReadDateByRoomObserver(RoomMessageView.java:1614)
        at PACKAGENAME.activities.chat.RoomMessageView.access$3400(RoomMessageView.java:104)
        at PACKAGENAME.activities.chat.RoomMessageView$24.run(RoomMessageView.java:1465)
        at java.lang.Thread.run(Thread.java:929)

zhangjiancheng avatar Feb 01 '21 02:02 zhangjiancheng

A few suggestions of things to check:

  1. Is the user signed out when this occurs?
  2. Do you have an app/src/main/res/raw/awsconfiguration.json present in your application project? If so, does this file contain an authentication section?
  3. Perhaps your phone is locked and so the the credentials are locked? This would apply on API level 30+.

jamesonwilliams avatar Feb 01 '21 21:02 jamesonwilliams

@jamesonwilliams

A few suggestions of things to check:

  1. Is the user signed out when this occurs? No. After landing, it was placed for two days, then it occured.
  1. Do you have an app/src/main/res/raw/awsconfiguration.json present in your application project? If so, does this file contain an authentication section? Yes. I have this json file. In fact, my application run well at normal. This is a issue that comes up by chance.
  1. Perhaps your phone is locked and so the the credentials are locked? This would apply on API level 30+. When the problem occurs, my phone is awake. And my testing phone's android version is Android 10 (API29).

zhangjiancheng avatar Feb 03 '21 06:02 zhangjiancheng

The same issue on Android 6,8,10. I don't have awsconfiguration.json file. Issue happens randomly. From Crashlytics I see that it happens 100% in background AppSync SDK Version: 3.1.1 @jamesonwilliams

ukevgen avatar Apr 07 '21 07:04 ukevgen

Hello, I'm also struggling with this issue. My app is running on Android 10.

Here's the awsconfiguration.json

{
    "UserAgent": "aws-amplify-cli/0.1.0",
    "Version": "0.1.0",
    "IdentityManager": {
        "Default": {}
    },

    "CognitoUserPool": {
        "Default": {
            "PoolId": "<HERE GOES POOL ID>",
            "AppClientId": "<HERE GOES CLIENT ID>",
            "Region": "<HER EGOES REGION>"
        }
    },

    "AppSync": {
        "Default": {
            "ApiUrl": "<HERE I HAVE API URL>",
            "Region": "<AND HERE IS THE REGION>",
            "AuthMode": "AMAZON_COGNITO_USER_POOLS",
            "ClientDatabasePrefix": "Backend_AMAZON_COGNITO_USER_POOLS"
        },
        "Backend_AWS_IAM": {
            "ApiUrl": "<HERE_GOES_URL>",
            "Region": "<REGION>",
            "AuthMode": "AWS_IAM",
            "ClientDatabasePrefix": "Backend_AWS_IAM"
        }
    }
}

Here's how the AWSAppSyncClient is created:

val configuration  = AWSConfiguration(applicationContext)
val cognitoUserPoolsAuthProvider = BasicCognitoUserPoolsAuthProvider(CognitoUserPool(applicationContext, configuration))
 AWSAppSyncClient.builder()
      .context(applicationContext)
      .awsConfiguration(configuration)
      .cognitoUserPoolsAuthProvider(cognitoUserPoolsAuthProvider)
      .build()

The user is signed in when the issue occurs.

First I'm getting the AppSyncSubscriptionCall.Callback::onFailure call on my active subscription. Then the Cognito Userpools failed to get session is happening. It seems that the issue occurs on low quality network, when device is loosing network connection from time to time (eg. user goes out of the WiFi range) It does not happened always - manual turning the internet connectivity off and on on the device usually does not trigger the issue.

wafel82 avatar Oct 05 '21 08:10 wafel82

Any suggestions?

zhangjiancheng avatar Mar 16 '22 07:03 zhangjiancheng

https://github.com/awslabs/aws-mobile-appsync-sdk-android/blob/cb79c1217c45373f414bf52d92499943fee65101/app/src/main/java/com/amazonaws/postsapp/ClientFactory.java look into this

itslonua avatar Jul 18 '22 09:07 itslonua

@itslonua are you trying to point to the PersistentMutationsCallback part in above link?

@div5yesh I'm also facing the same issue since few months. Unable to reproduce 100% time at my end but I can see many occurrences in Crashlytics logs.

I'm using: "com.amplifyframework:aws-auth-cognito:1.37.3"

I observed one thing from my Crashlytics though. Most of the times, it's either crashing immediately after login or it is crashing when user closes the app and returns to the app after few hours.

@zhangjiancheng did you find any solution for this?

ncs-ankur avatar Sep 19 '22 06:09 ncs-ankur

Is there any resolution for this. Its happening at least once per day per user. I am also on implementation "com.amplifyframework:aws-auth-cognito:1.37.3"

Fatal Exception: java.lang.RuntimeException: Cognito Userpools failed to get session
       at com.amazonaws.mobileconnectors.appsync.sigv4.BasicCognitoUserPoolsAuthProvider.fetchToken(BasicCognitoUserPoolsAuthProvider.java:80)
       at com.amazonaws.mobileconnectors.appsync.sigv4.BasicCognitoUserPoolsAuthProvider.getLatestAuthToken(BasicCognitoUserPoolsAuthProvider.java:86)
       at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getAuthorizationDetailsForUserpools(SubscriptionAuthorizer.java:171)
       at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getAuthorizationDetails(SubscriptionAuthorizer.java:88)
       at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getConnectionAuthorizationDetails(SubscriptionAuthorizer.java:65)
       at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.getConnectionRequestUrl(WebSocketConnectionManager.java:391)
       at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.createWebSocket(WebSocketConnectionManager.java:131)
       at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.retryAllSubscriptions(WebSocketConnectionManager.java:307)
       at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.access$800(WebSocketConnectionManager.java:45)
       at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager$2.handleMessage(WebSocketConnectionManager.java:244)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loopOnce(Looper.java:226)
       at android.os.Looper.loop(Looper.java:313)
       at android.os.HandlerThread.run(HandlerThread.java:67)

ksgangadharan avatar Dec 19 '22 18:12 ksgangadharan

Is this happening on lower version devices like <23 ? If not then I would highly recommend upgrading to Amplify V2 for all your Amplify needs including Auth and Appsync. That is built ontop of the latest kotlin sdk and redesigned entirely in Kotlin.

gpanshu avatar Mar 10 '23 17:03 gpanshu

@gpanshu Based on your recommendation we did try to upgrade to V2, however we have run into other issues on V2 ( see https://github.com/aws-amplify/amplify-android/issues/2331) which is a blocker for us.

On further debugging, this issue seems to happen when the client has internet connectivity issues and when the WebSocket tries to reconnect. We were able to reproduce using the following steps:

  1. Initializing amplify sdk
  2. simulate disrupting internet connectivity or disable internet
  3. wait for ~ 5 -10 mins
  4. The above exception occurs triggering an app crash

AnirudhWinimy avatar Mar 15 '23 03:03 AnirudhWinimy

We did try upgrading to implementation "com.amazonaws:aws-android-sdk-cognitoauth:2.64.0" . The BasicCognitoUserPoolsAuthProvider does not work at all after that. The following error is shown:

java.lang.RuntimeException: Cognito Userpools is not signed-in
at com.amazonaws.mobileconnectors.appsync.sigv4.BasicCognitoUserPoolsAuthProvider.fetchToken(BasicCognitoUserPoolsAuthProvider.java:80)
at com.amazonaws.mobileconnectors.appsync.sigv4.BasicCognitoUserPoolsAuthProvider.getLatestAuthToken(BasicCognitoUserPoolsAuthProvider.java:86)
at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getAuthorizationDetailsForUserpools(SubscriptionAuthorizer.java:171)
at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getAuthorizationDetails(SubscriptionAuthorizer.java:88)
at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getConnectionAuthorizationDetails(SubscriptionAuthorizer.java:65)
at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.getConnectionRequestUrl(WebSocketConnectionManager.java:391)
at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.createWebSocket(WebSocketConnectionManager.java:131)
at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.requestSubscription(WebSocketConnectionManager.java:90)
at com.amazonaws.mobileconnectors.appsync.AppSyncWebSocketSubscriptionCall.execute(AppSyncWebSocketSubscriptionCall.java:48)

ksgangadharan avatar Mar 16 '23 14:03 ksgangadharan

@ksgangadharan you are using the SDK. Please try updating to amplify

gpanshu avatar Mar 16 '23 14:03 gpanshu

@gpanshu getting the same error. So I changed to use amplify, below is my build.gradle

implementation "com.amplifyframework:core-kotlin:2.3.0"
implementation "com.amplifyframework:core:2.3.0"
implementation "com.amplifyframework:aws-auth-cognito:2.3.0"
implementation "com.amplifyframework:aws-storage-s3:2.3.0"
implementation "com.amplifyframework:aws-api:2.3.0"

implementation "com.amazonaws:aws-android-sdk-pinpoint:2.64.0"
implementation "com.amazonaws:aws-android-sdk-s3:2.64.0"
implementation 'com.amazonaws:aws-android-sdk-appsync:3.3.2'

And I am getting the same error as before:

CognitoUserSession is not valid because idToken is null.
java.lang.RuntimeException: Cognito Userpools is not signed-in
at com.amazonaws.mobileconnectors.appsync.sigv4.BasicCognitoUserPoolsAuthProvider.fetchToken(BasicCognitoUserPoolsAuthProvider.java:80)
at com.amazonaws.mobileconnectors.appsync.sigv4.BasicCognitoUserPoolsAuthProvider.getLatestAuthToken(BasicCognitoUserPoolsAuthProvider.java:86)
at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getAuthorizationDetailsForUserpools(SubscriptionAuthorizer.java:171)
at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getAuthorizationDetails(SubscriptionAuthorizer.java:88)
at com.amazonaws.mobileconnectors.appsync.SubscriptionAuthorizer.getConnectionAuthorizationDetails(SubscriptionAuthorizer.java:65)
at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.getConnectionRequestUrl(WebSocketConnectionManager.java:391)
at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.createWebSocket(WebSocketConnectionManager.java:131)
at com.amazonaws.mobileconnectors.appsync.WebSocketConnectionManager.requestSubscription(WebSocketConnectionManager.java:90)
at com.amazonaws.mobileconnectors.appsync.AppSyncWebSocketSubscriptionCall.execute(AppSyncWebSocketSubscriptionCall.java:48)

ksgangadharan avatar Mar 16 '23 16:03 ksgangadharan

@ksgangadharan just to understand your issue you login then after a period of inactivity call fetchAuthSession and you get this error ? If not then please provide reproduction steps.

gpanshu avatar Mar 16 '23 16:03 gpanshu

@gpanshu I login, and then I try to create the AWSAppSyncClient object

val cognitoUserPool = CognitoUserPool(context, AWSConfiguration(context))
val provider = BasicCognitoUserPoolsAuthProvider(cognitoUserPool)

val client = AWSAppSyncClient.builder()
    .context(context)
    .awsConfiguration(awsConfig)
    .cognitoUserPoolsAuthProvider(provider)
    .okHttpClient(okHttpClientBuilder.build())
    .s3ObjectManager(getS3ObjectManager(context))
    .build()

Note, that I did manage to make this work temporarily by replacing the provider with this code:

val provider = CognitoUserPoolsAuthProvider { (session as? AWSCognitoAuthSession)
                    ?.userPoolTokensResult?.value?.idToken }

where session was retrieved using Amplify.Auth.fetchAuthSession(). However this code has issues when the app is running for a long time

ksgangadharan avatar Mar 16 '23 16:03 ksgangadharan

What are the issues you are having with fetchAuthSession after the code has been running for a long time?

gpanshu avatar Mar 16 '23 17:03 gpanshu

@gpanshu there is no issue with fetchAuthSession. Problem is that fetchAuthSession is a coroutine and trying to integrate it with CognitoUserPoolsAuthProvider (which is a non coroutine code) is not straightforward and is prone to side effects

That's the reason why we need the BasicCognitoUserPoolsAuthProvider to work. Note that this code was working earlier when the amplify version was 1.37.3

ksgangadharan avatar Mar 16 '23 17:03 ksgangadharan

I see that you are using both the AWS Java SDK and Amplify together. They are not meant to be used together. Is there a use case you are trying to solve by using both of them. Have you tried only using Amplify V2 for Android to see if that solves your problem.

gpanshu avatar Mar 20 '23 17:03 gpanshu

There are 2 AWS sdk libraries that I am using, 1) Pinpoint library for registering for FCM notification, I don't see an alternative to that in the V2 amplify lib, and 2) the S3 library, and this is needed to attach a S3Object manager to the app sync client (refer AWSAppSyncClient.builder().s3ObjectManager(...)). I don't think there is an alternative for that .

Coming back to the original issue, what is the alternative for BasicCognitoUserPoolsAuthProvider. This is not referring to any of the AWS SDK classes, and it does not work

ksgangadharan avatar Mar 20 '23 18:03 ksgangadharan

I am also having the same issue using app sync with the latest amplify version. I am setting authentication with cognitoUserPoolsAuthProvider using the BasicCognitoUserPoolsAuthProvider.

This was working fine with latest amplify version 1.37.5 but does not work anymore with 2.14.9. The token is always null. Amplify session object that retrieves tokens has changed and I am not sure if this is related with that situation

iolandarosa7 avatar Jan 17 '24 17:01 iolandarosa7

@iolandarosa7 the 1.x version of Amplify depends on the AWS SDK for Android, which is compatible with the AppSync SDK here. However, the 2.x version of Amplify depends on the AWS SDK for Kotlin, which is not compatible with this library.

tjleing avatar Jan 18 '24 01:01 tjleing

@tjleing Thanks for your answer. For now, I implemented a custom auth provider that overrides the getLatestAuthToken method. It seems that with this app sync works fine. Anyway I will probably need to drop using app sync sdk in the future, and start using methods from Amplify GraphQL library.

Thanks

iolandarosa7 avatar Jan 18 '24 13:01 iolandarosa7