aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.44k stars 2.13k forks source link

fetchAuthSession failing on chrome android when putting back app to foreground #12955

Closed vcrepin closed 9 months ago

vcrepin commented 9 months ago

Before opening, please confirm:

JavaScript Framework

Angular

Amplify APIs

Authentication

Amplify Version

v6

Amplify Categories

auth

Backend

Amplify CLI

Environment information

``` # Put output below this line System: OS: macOS 14.2.1 CPU: (10) arm64 Apple M1 Max Memory: 6.53 GB / 64.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 18.17.0 - ~/.nvm/versions/node/v18.17.0/bin/node npm: 9.6.7 - ~/.nvm/versions/node/v18.17.0/bin/npm Browsers: Chrome: 121.0.6167.139 Safari: 17.2.1 npmPackages: @angular-builders/custom-webpack: ^17.0.0 => 17.0.0 @angular-devkit/build-angular: ^17.1.0 => 17.1.0 @angular/animations: ^17.1.0 => 17.1.0 @angular/cdk: ^17.1.0 => 17.1.0 @angular/cli: ^17.1.0 => 17.1.0 @angular/common: ^17.1.0 => 17.1.0 @angular/compiler: ^17.1.0 => 17.1.0 @angular/compiler-cli: ^17.1.0 => 17.1.0 @angular/core: ^17.1.0 => 17.1.0 @angular/forms: ^17.1.0 => 17.1.0 @angular/google-maps: ^17.1.0 => 17.1.0 @angular/localize: ^17.1.0 => 17.1.0 @angular/platform-browser: ^17.1.0 => 17.1.0 @angular/platform-browser-dynamic: ^17.1.0 => 17.1.0 @angular/router: ^17.1.0 => 17.1.0 @angular/service-worker: ^17.1.0 => 17.1.0 @aws-amplify/ui: ^6.0.8 => 6.0.8 @aws-amplify/ui-angular: ^5.0.8 => 5.0.8 @babel/core: ^7.23.7 => 7.23.7 (7.23.2) @kolkov/angular-editor: ^2.1.0 => 2.1.0 @sentry/angular-ivy: ^7.93.0 => 7.93.0 @sentry/browser: ^7.93.0 => 7.93.0 @sentry/integrations: ^7.93.0 => 7.93.0 @sentry/tracing: ^7.93.0 => 7.93.0 @sentry/webpack-plugin: ^1.20.1 => 1.21.0 @types/jest: ^29.5.11 => 29.5.11 @types/node: ^20.11.5 => 20.11.5 @types/proj4: ^2.5.5 => 2.5.5 @types/uuid: ^9.0.7 => 9.0.7 @types/webappsec-credential-management: ^0.6.8 => 0.6.8 @typescript-eslint/eslint-plugin: ^6.19.0 => 6.19.0 @typescript-eslint/parser: ^6.19.0 => 6.19.0 @zxing/browser: ^0.1.4 => 0.1.4 @zxing/library: ^0.20.0 => 0.20.0 @zxing/ngx-scanner: 17.0.0 => 17.0.0 amazon-cognito-identity-js: ^6.3.7 => 6.3.7 amazon-cognito-identity-js/internals: undefined () aws-amplify: ^6.0.13 => 6.0.13 aws-amplify/adapter-core: undefined () aws-amplify/analytics: undefined () aws-amplify/analytics/kinesis: undefined () aws-amplify/analytics/kinesis-firehose: undefined () aws-amplify/analytics/personalize: undefined () aws-amplify/analytics/pinpoint: undefined () aws-amplify/api: undefined () aws-amplify/api/server: undefined () aws-amplify/auth: undefined () aws-amplify/auth/cognito: undefined () aws-amplify/auth/cognito/server: undefined () aws-amplify/auth/enable-oauth-listener: undefined () aws-amplify/auth/server: undefined () aws-amplify/datastore: undefined () aws-amplify/in-app-messaging: undefined () aws-amplify/in-app-messaging/pinpoint: undefined () aws-amplify/push-notifications: undefined () aws-amplify/push-notifications/pinpoint: undefined () aws-amplify/storage: undefined () aws-amplify/storage/s3: undefined () aws-amplify/storage/s3/server: undefined () aws-amplify/storage/server: undefined () aws-amplify/utils: undefined () aws-sdk: ^2.1538.0 => 2.1538.0 axios: 1.6.5 => 1.6.5 babel-eslint: ^10.1.0 => 10.1.0 base64url: ^3.0.1 => 3.0.1 cbor: ^9.0.1 => 9.0.1 crypto-browserify: ^3.12.0 => 3.12.0 date-fns: ^3.2.0 => 3.2.0 (2.30.0) dexie: ^3.2.4 => 3.2.4 eslint: ^8.56.0 => 8.56.0 eslint-config-prettier: ^9.1.0 => 9.1.0 eslint-plugin-prettier: ^5.1.3 => 5.1.3 eslint-plugin-rxjs: ^5.0.3 => 5.0.3 eslint-plugin-unused-imports: ^3.0.0 => 3.0.0 example-typescript: 1.0.0 hammerjs: ^2.0.8 => 2.0.8 jest: ^29.7.0 => 29.7.0 jest-preset-angular: ^14.0.0 => 14.0.0 jwt-decode: ^4.0.0 => 4.0.0 ng-speed-test: ^2.6.1 => 2.6.1 ng-zorro-antd: ^17.2.0 => 17.2.0 ngx-i18nsupport: ^0.17.1 => 0.17.1 node-polyfill-webpack-plugin: ^3.0.0 => 3.0.0 ol: 8.1.0 => 8.1.0 prettier: ^3.2.4 => 3.2.4 proj4: ^2.10.0 => 2.10.0 protractor: ~7.0.0 => 7.0.0 rxjs: ~7.8.1 => 7.8.1 (6.6.7) rxjs/ajax: undefined () rxjs/fetch: undefined () rxjs/internal-compatibility: undefined () rxjs/operators: undefined () rxjs/testing: undefined () rxjs/webSocket: undefined () signature_pad: ^4.1.7 => 4.1.7 stream-browserify: ^3.0.0 => 3.0.0 ts-jest: ^29.1.1 => 29.1.1 ts-node: ~10.9.2 => 10.9.2 tslib: ^2.6.2 => 2.6.2 (1.14.1) typescript: ~5.2.2 => 5.2.2 util: ^0.12.5 => 0.12.5 utm-latlng: ^1.0.8 => 1.0.8 uuid: ^9.0.1 => 9.0.1 (8.3.2, 8.0.0, 3.4.0) webpack-bundle-analyzer: ^4.10.1 => 4.10.1 xlsx: ^0.18.5 => 0.18.5 zone.js: ~0.14.3 => 0.14.3 npmGlobalPackages: @angular/cli: 16.2.9 corepack: 0.18.0 npm: 9.6.7 ```

Describe the bug

I use amplify auth for an angular app. After signIn, I refresh the session with fetchAuthSession() each 5 min or when the app has been put to background and put back to foreground. The app is packaged as a PWA. This works well everywhere except on my android phone (chrome browser). When the app is put back to foreground and refreshAuthSession is called it fails with the following error:

Unexpected end of JSON input

I can see that this is raised in the library fetch method and I also see in the logs that the call to

POST https://cognito-idp.us-east-1.amazonaws.com/ [504]

returned a 504 error.

The expiration of my tokens is quite long (many hours) so they should not be expired.

The problem happens when I leave the app in the background a certain time and work on other apps before putting it back to foreground.

Expected behavior

Should refresh the session as it does on all other plateforms

Reproduction steps

Start app on cell phone (PWA) put it to background play with other apps put back app to foreground

Code Snippet

// Put your code below this line.

public async refreshSession(forceRefresh = true): Promise<any> {
    let authSession = undefined;
    try {
      if (this.authenticatorService.authStatus === 'authenticated') {
        authSession = await fetchAuthSession({ forceRefresh });
        await this.updateAWS(authSession);
        const user = await getCurrentUser();
        const attributes = await fetchUserAttributes();
        this.apiService.user = { username: user.username, attributes: attributes };
        Sentry.setUser(this.apiService.user);
        if (this.apiService.user) {
          localStorage.setItem(
            'authData',
            JSON.stringify({
              username: user.username,
              attributes: { ...attributes },
            }),
          );
        }
        const jwtTokens = authSession.tokens;
        const decoded = jwtDecode<JwtPayload>(jwtTokens?.idToken?.toString() ?? '');
        this.userService.decodedToken = decoded;
        localStorage.setItem('decodedToken', JSON.stringify(decoded));
        await this.storeCredentials(authSession);
      }
      console.warn('authStatus', this.authenticatorService.authStatus);
    } catch (error) {
      if (this.authenticatorService.error) {
        Sentry.captureMessage('AmplifyService-refreshSession: ' + this.authenticatorService.error, {
          tags: {
            online: navigator.onLine,
            networkSpeed: (navigator as any).connection?.downlink,
            rtt: (navigator as any).connection?.rtt,
            networkType: (navigator as any).connection?.type,
            networkEffectiveType: (navigator as any).connection?.effectiveType,
            version: environment.version,
          },
        });
      }
      Sentry.captureException(error, {
        tags: {
          online: navigator.onLine,
          networkSpeed: (navigator as any).connection?.downlink,
          rtt: (navigator as any).connection?.rtt,
          networkType: (navigator as any).connection?.type,
          networkEffectiveType: (navigator as any).connection?.effectiveType,
          version: environment.version,
        },
      });
      // on some devices we sometimes get 504 from POST to https://cognito-idp.us-east-1.amazonaws.com/
      // reloading for now...
      setTimeout(() => {
        this.ngZone.run(() => {
          if (navigator.onLine) {
            window.location.reload();
          }
        });
      }, 100);
      return null;
    }
    return authSession;
  }

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

Chrome (PWA)

Mobile Browser Version

No response

Additional information and screenshots

No response

vcrepin commented 9 months ago
Screenshot 2024-02-04 at 14 07 28
vcrepin commented 9 months ago

This is the place that it fails according to Sentry trace

vcrepin commented 9 months ago

I found the problem.

The phone had the data economy feature on. This prevented the calls in the background to succeed.

cwomack commented 9 months ago

Hey, @vcrepin 👋. Glad you already found the problem and unblocked yourself! Also, thank you for creating this issue because I've actually never read about the Data Saver feature within Android devices. Appreciate the education moment!

For anyone that comes across this issue, please refer to the Android docs to learn more about Data Saver mode. While it can reduce data usage by limiting background data and optimizing foreground app data usage, that restriction on the background data can affect performance and network calls. Looks like Cognito calls were impacted in this situation when the app was bring brought back to foreground.

I'll close this issue as resolved since you unblocked yourself so quickly, but feel free to comment back if that's not the case @vcrepin! Thanks.