aws-amplify / amplify-flutter

A declarative library with an easy-to-use interface for building Flutter applications on AWS.
https://docs.amplify.aws
Apache License 2.0
1.31k stars 243 forks source link

Amplify configure() throwing PushNotificationException after refresh token has expired #5109

Closed sergiu-oanea closed 2 months ago

sergiu-oanea commented 3 months ago

Description

Our app uses the Amplify Auth and the AmplifyPushNotificationsPinpoint.

We run into the following exception when calling Amplify.configure() when the user opens the app after the refresh token has expired.

PushNotificationException {
  "message": "Error occurred awaiting for device token to register device with Pinpoint",
  "recoverySuggestion": "Please review the underlying exception",
  "underlyingException": "UnknownException {\n  \"message\": \"The AWS credentials could not be retrieved\",\n  \"recoverySuggestion\": \"Invoke Amplify.Auth.signIn to re-authenticate the user\",\n  \"underlyingException\": \"NotAuthorizedException {\\n  message=Invalid login token. Token expired: 1720006497 >= 1720002867,\\n}\"\n}"
} 

Please note that this exception we only get the first time the app is opened after the token has expired. We don't get it anymore the second time (if the app is killed and opened back again).

In normal flows, when session is still active, or user is not authenticated the call to Amplify.configure() is successful.

We have the exact same issue as this one: https://github.com/aws-amplify/amplify-flutter/issues/3950 which is supposed to be fixed in v1.5.0

What we want to achieve is to redirect the user to login screen in case the refresh token has expired to start a new session. We cannot check to see if session has expired because the Amplify.configure() crashes. Not sure how to accomplish this.

We are using flutter 3.22.0 and amplify-flutter 2.2.0

This is the main.dart file ``` void main() async { try { runZonedGuarded( () async { WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = (FlutterErrorDetails details) { log.e( 'FlutterError.onError()', error: details.exception, stackTrace: details.stack, ); }; // get configuration file final appConfig = await AppConfig.forEnvironment(''); // initialize Amplify await configureAmplify(appConfig); // initialize GetStorage await GetStorage.init(); // get translations var translations = await TranslationService().getAllTranslations(); // initialize timezones tz.initializeTimeZones(); runApp(MyApp(translations, appConfig)); }, (error, stackTrace) { log.e( 'runZonedGuarded()', error: error, stackTrace: stackTrace, ); }, ); } catch (error, stackTrace) { log.e( 'Main()', error: error, stackTrace: stackTrace, ); } } Future configureAmplify(AppConfig appConfig) async { try { final auth = AmplifyAuthCognito(); final api = AmplifyAPI(); final pushPlugin = AmplifyPushNotificationsPinpoint(); await Amplify.addPlugins([auth, api, pushPlugin]); await Amplify.configure(appConfig.amplify); } on Exception catch (e, s) { log.e('An error occurred configuring Amplify: $e', stackTrace: s); } } class MyApp extends StatelessWidget { final Map> translations; final AppConfig appConfig; const MyApp(this.translations, this.appConfig, {super.key}); @override Widget build(BuildContext context) { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); return GestureDetector( onTap: () => keyboardDismissHandler(context), child: GetMaterialApp( title: 'appName'.tr, theme: theme(), initialBinding: InitialBindings(appConfig), getPages: Pages.routes, initialRoute: Pages.initial, translations: AppTranslations(translations: translations), locale: TranslationService.locale, fallbackLocale: TranslationService.fallbackLocale, logWriterCallback: _logWriterCallback, ), ); } void _logWriterCallback(String text, {bool isError = false}) { final logMessage = '[GetX] $text'; if (isError) { log.e(logMessage); } else { log.i(logMessage); } } keyboardDismissHandler(BuildContext context) { // Global Keyboard Dismiss log.d('on Tap Dismiss Keyboard'); FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { FocusManager.instance.primaryFocus?.unfocus(); } } } ```
Amplify config json ``` "amplify": { "UserAgent": "aws-amplify-cli/2.0", "Version": "1.0", "notifications": { "plugins": { "awsPinpointPushNotificationsPlugin": { "appId": "[SECRET]", "region": "[SECRET]" } } }, "auth": { "plugins": { "awsCognitoAuthPlugin": { "UserAgent": "aws-amplify-cli/0.1.0", "Version": "0.1.0", "IdentityManager": { "Default": {} }, "CredentialsProvider": { "CognitoIdentity": { "Default": { "PoolId": "[SECRET]", "Region": "[SECRET]" } } }, "CognitoUserPool": { "Default": { "PoolId": "[SECRET]", "AppClientId": "[SECRET]", "Region": "[SECRET]" } }, "Auth": { "Default": { "authenticationFlowType": "USER_SRP_AUTH" } } } } }, "api": { "plugins": { "awsAPIPlugin": { "DeviceProvision": { "endpointType": "REST", "endpoint": "[SECRET]", "region": "[SECRET]", "authorizationType": "AMAZON_COGNITO_USER_POOLS" } } } } } ```

Categories

Steps to Reproduce

  1. Use Auth & AmplifyPushNotificationsPinpoint service
  2. Authenticate user
  3. Kill the app
  4. Wait util the refresh token has expired
  5. Open the app again
  6. The PushNotificationException is thrown when calling Amplify.configure() in main()
  7. If the app is killed and opened again we don't get that exception anymore. We get it only the first time after time the user opens the app after the token has expired.

Screenshots

No response

Platforms

Flutter Version

3.22.0

Amplify Flutter Version

2.2.0

Deployment Method

Amplify CLI

Schema

No response

NikaHsn commented 3 months ago

Sorry that you are facing this issue and thanks for reporting it. We will look into this and get back to you when we have updates.

sergiu-oanea commented 2 months ago

@NikaHsn, @khatruong2009

I've seen this is fixed in this opened PR: https://github.com/aws-amplify/amplify-flutter/pull/5117

Do you guys know when the PR will be merged and in what release it will be included?

Thanks

khatruong2009 commented 2 months ago

Hi @sergiu-oanea, this PR has been merged and is marked pending release. We are working on a release soon and will let you know when it is out.

Equartey commented 2 months ago

Hi @sergiu-oanea, this has been released in Amplify Flutter 2.3.0. Please let us know if you have any more concerns.