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.42k stars 2.12k forks source link

Auth functions don't work in the release version of the app, but only in the development ones #13588

Closed Catazza closed 2 months ago

Catazza commented 2 months ago

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

Authentication

Amplify Version

v6

Amplify Categories

auth

Backend

Amplify Gen 2 (Preview)

Environment information

``` # Put output below this line System: OS: macOS 13.6.3 CPU: (10) arm64 Apple M1 Max Memory: 228.23 MB / 32.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 20.3.0 - ~/.nvm/versions/node/v20.3.0/bin/node Yarn: 1.22.19 - ~/.nvm/versions/node/v20.3.0/bin/yarn npm: 9.6.7 - ~/.nvm/versions/node/v20.3.0/bin/npm pnpm: 9.5.0 - ~/.nvm/versions/node/v20.3.0/bin/pnpm Browsers: Chrome: 126.0.6478.127 Safari: 16.6 npmPackages: %name%: 0.1.0 @aws-amplify/backend: ^1.0.3 => 1.0.3 @aws-amplify/backend-cli: ^1.0.4 => 1.0.4 @aws-amplify/react-native: ^1.1.1 => 1.1.1 @aws-amplify/storage: ^6.4.6 => 6.4.6 @aws-amplify/storage/s3: undefined () @aws-amplify/storage/s3/server: undefined () @aws-amplify/storage/server: undefined () @aws-amplify/ui-react: ^6.1.12 => 6.1.12 @aws-amplify/ui-react-internal: undefined () @aws-amplify/ui-react-native: ^2.2.2 => 2.2.2 @babel/core: ^7.20.0 => 7.24.7 @expo/vector-icons: ^14.0.0 => 14.0.2 @react-native-async-storage/async-storage: 1.23.1 => 1.23.1 @react-native-community/netinfo: ^11.3.2 => 11.3.2 @react-navigation/native: ^6.0.2 => 6.1.17 @types/jest: ^29.5.12 => 29.5.12 @types/react: ~18.2.45 => 18.2.79 @types/react-test-renderer: ^18.0.7 => 18.3.0 HelloWorld: 0.0.1 aws-amplify: ^6.3.6 => 6.3.6 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/data: undefined () aws-amplify/data/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-cdk: ^2.146.0 => 2.146.0 aws-cdk-lib: ^2.146.0 => 2.146.0 axios: ^1.7.2 => 1.7.2 base-64: ^1.0.0 => 1.0.0 constructs: ^10.3.0 => 10.3.0 esbuild: ^0.21.5 => 0.21.5 expo: ~51.0.10 => 51.0.10 expo-av: ^14.0.5 => 14.0.5 expo-camera: ~15.0.11 => 15.0.11 expo-constants: ~16.0.2 => 16.0.2 expo-dev-client: ~4.0.18 => 4.0.18 expo-font: ~12.0.7 => 12.0.7 expo-linear-gradient: ~13.0.2 => 13.0.2 expo-linking: ~6.3.1 => 6.3.1 expo-localization: ~15.0.3 => 15.0.3 expo-media-library: ^16.0.3 => 16.0.3 expo-router: ~3.5.15 => 3.5.15 expo-splash-screen: ~0.27.4 => 0.27.4 expo-status-bar: ~1.12.1 => 1.12.1 expo-system-ui: ~3.0.5 => 3.0.5 expo-web-browser: ~13.0.3 => 13.0.3 i18next: ^23.11.5 => 23.11.5 jest: ^29.2.1 => 29.7.0 jest-expo: ~51.0.1 => 51.0.2 nativewind: ^2.0.11 => 2.0.11 react: 18.2.0 => 18.2.0 react-dom: 18.2.0 => 18.2.0 react-i18next: ^14.1.2 => 14.1.2 react-native: 0.74.1 => 0.74.1 react-native-fetch-api: ^3.0.0 => 3.0.0 react-native-gesture-handler: ~2.16.1 => 2.16.2 react-native-get-random-values: ^1.11.0 => 1.11.0 react-native-polyfill-globals: ^3.1.0 => 3.1.0 react-native-reanimated: ~3.10.1 => 3.10.1 react-native-safe-area-context: ^4.10.1 => 4.10.1 react-native-screens: 3.31.1 => 3.31.1 react-native-svg: 15.2.0 => 15.2.0 react-native-track-player: ^4.1.1 => 4.1.1 react-native-url-polyfill: ^1.3.0 => 1.3.0 (2.0.0) react-native-uuid: ^2.0.2 => 2.0.2 react-native-web: ~0.19.10 => 0.19.12 react-test-renderer: 18.2.0 => 18.2.0 recoil: ^0.7.7 => 0.7.7 shaka-player: ^4.9.5 => 4.9.6 tailwindcss: 3.3.2 => 3.3.2 text-encoding: ^0.7.0 => 0.7.0 tsx: ^4.15.5 => 4.15.5 typescript: ~5.3.3 => 5.3.3 (4.4.4, 4.9.5) web-streams-polyfill: ^3.2.1 => 3.2.1 (3.3.3) web-streams-polyfill-es2018: undefined () web-streams-polyfill-es6: undefined () web-streams-ponyfill: undefined () web-streams-ponyfill-es2018: undefined () web-streams-ponyfill-es6: undefined () npmGlobalPackages: @aws-amplify/cli: 12.12.2 @expo/ngrok: 4.1.3 corepack: 0.18.0 eas-cli: 10.1.1 npm: 9.6.7 ```

Describe the bug

I had already opened this issue in Amplify-UI originally, as I thought it was a bug with the UI component. However, upon further exploration we noticed it's a general issue.

In particular, auth functions such as signIn don't work in the release (production) versions of the app. We are using expo. In the development builds, everything works as expected. When I create a release for example with npx expo run:ios --configuration Release the functions stop working (clicking on the login button nothing happens). I have checked AWS cloudtrail, and I do see that Cognito indeed receives the requests, and answers successfully. I have tried both the SRP and PASSWORD. Auth flows, but neither works. The issue happens both on iOS and Android.

Expected behavior

Login function should work the same in release as in the development builds

Reproduction steps

  1. Build the app with npx expo run:ios --configuration Release
  2. try logging in with an existing user

Code Snippet

root component:

import { Stack } from "expo-router";
import { Amplify } from "aws-amplify";
import outputs from "@/amplify_outputs.json";
import { RecoilRoot } from "recoil";
import { useEffect } from "react";
import '@/i18n';
import { useFonts } from 'expo-font';
import { Authenticator, ThemeProvider } from "@aws-amplify/ui-react-native";
import 'react-native-polyfill-globals/auto';

Amplify.configure(outputs);

export default function RootLayout() {

  const [loaded, error] = useFonts({
    'InstrumentSans': require('@/assets/fonts/InstrumentSans/InstrumentSans-Regular.ttf'),
  });

  return (
    <ThemeProvider
      theme={{
        tokens: {
          colors: {
            primary: {
              '10': '#bf5e40',
              '80': '#bf5e40',
              '90': '#bf5e40',
              '100': '#bf5e40',
            },
            background: {
              primary: '#f9f6f2'
            }
          },
        }
      }}
    >
      <Authenticator.Provider>
        <RecoilRoot>
          <PlayerProvider>
            <Stack screenOptions={{ headerShown: false }}>
              <Stack.Screen name="index" />
              <Stack.Screen name="(intro)" />
              <Stack.Screen name="(login)" />
            </Stack>
          </PlayerProvider>
        </RecoilRoot>
      </Authenticator.Provider>
    </ThemeProvider>
  );
}

index.tsx at root

import React, { useEffect } from 'react';
import { router } from 'expo-router';
import { getCurrentUser } from 'aws-amplify/auth';
import { View } from 'react-native';

const EntryComponent: React.FC = () => {

    const checkUserLoggedIn = async () => {
        try {
          const res = await getCurrentUser()
          if(!res) return false
          console.log('res: ',res.signInDetails)
          return !!res.signInDetails
        } catch (error) {
          console.log(error)
          return false
        }
      }

    useEffect(() => {
        const fetchData = async () => {
            const isLoggedIn = await checkUserLoggedIn();

            if (isLoggedIn) {
                router.push('/mode');
            } else {
                router.push('/intro');
            }
        };

        fetchData();
    }, []);

    return <>
    <View></View>
    </>;
};
export default EntryComponent;

intro.tsx

import Button from '@/components/Button';
import HeaderTitle from '@/components/HeaderTitle';
import React, { useState, useEffect } from 'react';
import { SafeAreaView, Text, View, Image } from 'react-native';
import { Link, router } from 'expo-router';
import { getCurrentUser } from 'aws-amplify/auth';
import { signIn, confirmSignIn } from 'aws-amplify/auth';

const HomeScreen: React.FC = () => {

  const handleGetStarted = async () => {
    const { nextStep } = await signIn({
      username: 'user123',
      password: "xxxx"
    });
    console.log('nextStep is: ', nextStep);
    if (nextStep.signInStep==="DONE") {
      console.log('succesfully signed in');
      router.push('/mode');   // works in the dev build but not the release ones
    }
  }

  return (
    <SafeAreaView className="h-full">
      <View className="h-full bg-background p-4">
        <HeaderTitle />
        <View className="flex-1 justify-center items-center">
          <Text className="text-text text-4xl font-bold text-center mb-4 h-36">
            Hello there
          </Text>
          <Text className="text-text text-center w-2/3">
            Welcome
          </Text>
        </View>
        <View className="justify-end items-center pb-8">
          <Button onPress={handleGetStarted} className="mb-4">
            Get started
          </Button>
        </View>
      </View>
    </SafeAreaView>
  );
};

export default HomeScreen;

button component:

// components/Button.tsx
import React from 'react';
import { TouchableOpacity, Text } from 'react-native';

interface ButtonProps {
  onPress: () => void;
  children: string;
  classComponent?: string;
  disabled?: boolean;
}

const Button: React.FC<ButtonProps> = ({ onPress, children, classComponent, disabled }) => {
  return (
    <TouchableOpacity onPress={onPress} disabled={disabled} className={`bg-primary rounded-full w-full py-4 ${disabled && 'opacity-60'} ${classComponent}`}>
      <Text className="text-textInverted text-center font-bold">{children}</Text>
    </TouchableOpacity>
  );
};

export default Button;

Log output

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

aws-exports.js

aws_outputs.js file:

{
  "auth": {
    "user_pool_id": "xxx",
    "aws_region": "eu-central-1",
    "user_pool_client_id": "xxx",
    "identity_pool_id": "xxx",
    "mfa_methods": [],
    "standard_required_attributes": [
      "email"
    ],
    "username_attributes": [
      "email"
    ],
    "user_verification_types": [
      "email"
    ],
    "mfa_configuration": "OFF",
    "password_policy": {
      "min_length": 8,
      "require_numbers": true,
      "require_lowercase": true,
      "require_uppercase": true,
      "require_symbols": true
    },
    "unauthenticated_identities_enabled": true
  },
  "data": {
    "url": "xxx",
    "aws_region": "eu-central-1",
    "default_authorization_type": "AMAZON_COGNITO_USER_POOLS",
    "authorization_types": [
      "AWS_IAM"
    ],
    "model_introspection": {
      "version": 1,
      "models": {
        "UserPreferences": {
          "name": "UserPreferences",
          "fields": {
            "userId": {
              "name": "userId",
              "isArray": false,
              "type": "ID",
              "isRequired": true,
              "attributes": []
            },
            "preference": {
              "name": "preference",
              "isArray": false,
              "type": {
                "enum": "UserPreferencesPreference"
              },
              "isRequired": false,
              "attributes": []
            },
            "createdAt": {
              "name": "createdAt",
              "isArray": false,
              "type": "AWSDateTime",
              "isRequired": false,
              "attributes": [],
              "isReadOnly": true
            },
            "updatedAt": {
              "name": "updatedAt",
              "isArray": false,
              "type": "AWSDateTime",
              "isRequired": false,
              "attributes": [],
              "isReadOnly": true
            }
          },
          "syncable": true,
          "pluralName": "UserPreferences",
          "attributes": [
            {
              "type": "model",
              "properties": {}
            },
            {
              "type": "key",
              "properties": {
                "fields": [
                  "userId"
                ]
              }
            },
            {
              "type": "auth",
              "properties": {
                "rules": [
                  {
                    "provider": "userPools",
                    "ownerField": "owner",
                    "allow": "owner",
                    "identityClaim": "cognito:username",
                    "operations": [
                      "create",
                      "update",
                      "delete",
                      "read"
                    ]
                  }
                ]
              }
            }
          ],
          "primaryKeyInfo": {
            "isCustomPrimaryKey": true,
            "primaryKeyFieldName": "userId",
            "sortKeyFieldNames": []
          }
        }
      },
      "enums": {
        "UserPreferencesPreference": {
          "name": "UserPreferencesPreference",
          "values": [
            "1",
            "2"
          ]
        }
      },
      "nonModels": {}
    }
  },
  "storage": {
    "aws_region": "eu-central-1",
    "bucket_name": "xxx"
  },
  "version": "1",
  "custom": {
    "backendApiUrl": "xxx"
  }
}

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

package.json

{
  "name": "myapp",
  "main": "expo-router/entry",
  "version": "1.0.0",
  "scripts": {
    "start": "expo start",
    "reset-project": "node ./scripts/reset-project.js",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web",
    "test": "jest --watchAll",
    "lint": "expo lint"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@aws-amplify/react-native": "^1.1.1",
    "@aws-amplify/storage": "^6.4.6",
    "@aws-amplify/ui-react": "^6.1.12",
    "@aws-amplify/ui-react-native": "^2.2.2",
    "@expo/vector-icons": "^14.0.0",
    "@react-native-async-storage/async-storage": "1.23.1",
    "@react-native-community/netinfo": "^11.3.2",
    "@react-navigation/native": "^6.0.2",
    "aws-amplify": "^6.3.6",
    "axios": "^1.7.2",
    "base-64": "^1.0.0",
    "expo": "~51.0.10",
    "expo-av": "^14.0.5",
    "expo-camera": "~15.0.11",
    "expo-constants": "~16.0.2",
    "expo-dev-client": "~4.0.18",
    "expo-font": "~12.0.7",
    "expo-linking": "~6.3.1",
    "expo-localization": "~15.0.3",
    "expo-media-library": "^16.0.3",
    "expo-router": "~3.5.15",
    "expo-splash-screen": "~0.27.4",
    "expo-status-bar": "~1.12.1",
    "expo-system-ui": "~3.0.5",
    "expo-web-browser": "~13.0.3",
    "i18next": "^23.11.5",
    "nativewind": "^2.0.11",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-i18next": "^14.1.2",
    "react-native": "0.74.1",
    "react-native-fetch-api": "^3.0.0",
    "react-native-gesture-handler": "~2.16.1",
    "react-native-get-random-values": "^1.11.0",
    "react-native-polyfill-globals": "^3.1.0",
    "react-native-reanimated": "~3.10.1",
    "react-native-safe-area-context": "^4.10.1",
    "react-native-screens": "3.31.1",
    "react-native-track-player": "^4.1.1",
    "react-native-url-polyfill": "^1.3.0",
    "react-native-uuid": "^2.0.2",
    "react-native-web": "~0.19.10",
    "recoil": "^0.7.7",
    "shaka-player": "^4.9.5",
    "text-encoding": "^0.7.0",
    "web-streams-polyfill": "^3.2.1",
    "expo-linear-gradient": "~13.0.2",
    "react-native-svg": "15.2.0"
  },
  "devDependencies": {
    "@aws-amplify/backend": "^1.0.3",
    "@aws-amplify/backend-cli": "^1.0.4",
    "@babel/core": "^7.20.0",
    "@types/jest": "^29.5.12",
    "@types/react": "~18.2.45",
    "@types/react-test-renderer": "^18.0.7",
    "aws-cdk": "^2.146.0",
    "aws-cdk-lib": "^2.146.0",
    "constructs": "^10.3.0",
    "esbuild": "^0.21.5",
    "jest": "^29.2.1",
    "jest-expo": "~51.0.1",
    "react-test-renderer": "18.2.0",
    "tailwindcss": "3.3.2",
    "tsx": "^4.15.5",
    "typescript": "~5.3.3"
  },
  "optionalDependencies": {
    "@parcel/watcher-linux-x64-glibc": "2.4.1"
  },
  "private": true
}
cwomack commented 2 months ago

Hello, @Catazza 👋. We'll close this issue as a duplicate of #13587 since that was transferred from the UI repo. We can reference anything from this issue if needed, but we'll follow up with further on the other issue. Thanks!