Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authenticator component works in expo development builds but not in production #13587

Closed
4 tasks done
Catazza opened this issue Jul 11, 2024 · 17 comments
Closed
4 tasks done
Assignees
Labels
Auth Related to Auth components/category pending-maintainer-response Issue is pending a response from the Amplify team. question General question transferred This issue was transferred from another Amplify project

Comments

@Catazza
Copy link

Catazza commented Jul 11, 2024

Before creating a new issue, please confirm:

On which framework/platform are you having an issue?

React Native

Which UI component?

Authenticator

How is your app built?

Expo Application Services

What browsers are you seeing the problem on?

iOS (React Native), Android (React Native)

Which region are you seeing the problem in?

No response

Please describe your bug.

The authenticator component work fine in iOS and Android simulators. It also works fine on real devices with expo development builds. However, it does not work when moving to production builds. This happens for both signin of already existing users, and sign up of new users:

login signup

The weird thing is that Cognito in the backed does receive the API calls. The user for example gets created, with uncorfirmed passwords.

cognito

I looked at AWS Cloudtrail events, and the API calls between the development builds and the production builds look identical.

What's the expected behaviour?

The component works identically between development and production builds.

Help us reproduce the bug!

Here is how we use the authenticator component in out _layout.tsx file:

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


TrackPlayer.registerPlaybackService(() => require('@/helpers/service'));
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.Screen name="(talk)" />
              <Stack.Screen name="(camera)" />
              <Stack.Screen name="(profile)" />
            </Stack>
          </PlayerProvider>
        </RecoilRoot>
      </Authenticator.Provider>
    </ThemeProvider>
  );
}

Here is the 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 start --android",
    "ios": "expo start --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
}

Here is the screen with the actual login:

import React, { useEffect, useState } from "react";
import { Button, View, StyleSheet, SafeAreaView } from "react-native";

import { Authenticator, useAuthenticator } from "@aws-amplify/ui-react-native";
import { Hub } from 'aws-amplify/utils';
import { I18n } from 'aws-amplify/utils';
import { translations } from '@aws-amplify/ui';
import { getLanguage } from "@/helpers/locales";
import { router } from "expo-router";

Hub.listen('auth', ({ payload }) => {
  switch (payload.event) {
    case 'signedIn':
      console.log('user have been signedIn successfully.');
      router.push('/mode')
      break;
    case 'signedOut':
      console.log('user have been signedOut successfully.');
      router.push('/intro')
      break;
    case 'tokenRefresh':
      console.log('auth tokens have been refreshed.');
      break;
    case 'tokenRefresh_failure':
      console.log('failure while refreshing auth tokens.');
      break;
    case 'signInWithRedirect':
      console.log('signInWithRedirect API has successfully been resolved.');
      break;
    case 'signInWithRedirect_failure':
      console.log('failure while trying to resolve signInWithRedirect API.');
      break;
    case 'customOAuthState':
      console.log('custom state returned from CognitoHosted UI');
      break;
  }
});

I18n.putVocabularies({
  it: {
    'Enter your Password': 'Inserisci la tua password',
    'Please confirm your Password': 'Conferma la password',
    'Given Name': "Nome",
    'Enter your Given Name': 'Inserisci il tuo nome',
    'Family Name': "Cognome",
    'Enter your Family Name': 'Inserisci il tuo cognome',
  }
});

const Login = () => {

  const [language, setLanguage] = useState('en')
  const initLang = () => getLanguage().then((lang) =>  {
    I18n.putVocabularies(translations)
    I18n.setLanguage(lang)
    setLanguage(lang)
  })
  useEffect(() => {
    initLang()
  }, [language])

  const SignOutButton = () => {
    const { signOut } = useAuthenticator();
  
    return (
      <View style={styles.signOutButton}>
        <Button title="Sign Out" onPress={signOut} />
      </View>
    );
  };

  return (
        <Authenticator loginMechanisms={['email']} signUpAttributes={[
          "given_name",
          "family_name",
          "email"
        ]}>
          <SafeAreaView>
            <SignOutButton />
          </SafeAreaView>
        </Authenticator>
  );
};

const styles = StyleSheet.create({
  signOutButton: {
    alignSelf: "flex-end",
  },
  
});

export default Login;

Code Snippet

// Put your code below this line.

Console log output

N/A it's a production build

Additional information and screenshots

No response

@github-actions github-actions bot added the pending-triage Issue is pending triage label Jul 11, 2024
@timngyn timngyn self-assigned this Jul 11, 2024
@timngyn
Copy link
Member

timngyn commented Jul 11, 2024

👋 Hi @Catazza, sorry you're having this issue. Just to confirm, when you say "production build", is it the production build from EAS? What command are you using?

@Catazza
Copy link
Author

Catazza commented Jul 11, 2024

👋 Hi @Catazza, sorry you're having this issue. Just to confirm, when you say "production build", is it the production build from EAS? What command are you using?

Hi @timngyn thanks for replying :) To be precise, it's in fact the preview the build with EAS that is without development client, which we push to App Store Connect or the Play store in order to do user testing. If I install directly the Android build (without passing from the Play Store) I still face the same issue.

I used the preview profile in this eas.json:

{
  "cli": {
    "version": ">= 10.0.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal"
    },
    "submit": {
      "production": {}
    }
  }
}

@reesscot
Copy link
Contributor

reesscot commented Jul 12, 2024

@Catazza We don't directly support builds using EAS cloud services. To better isolate the issue, are you able to do a production build using Expo in your local development environment (outside of EAS)?

Another thing you could try to isolate the issue would be to remove the Authenticator and use the Amplify JS signIn function directly: https://docs.amplify.aws/react-native/build-a-backend/auth/connect-your-frontend/sign-in/

@Catazza
Copy link
Author

Catazza commented Jul 12, 2024

Hi @reesscot yes I also did try that, also local builds present the same issue. I can share some build logs if you wish? There's loads so I won't paste the whole block here!

And yes thanks for the suggestion, I am already onto trying the SignIn function - also because, I noticed in cloudtrail that the signIn event is responded with the challenge (for the SRP auth flow) and this is where it gets stuck. So I will also try with the "normal" password flow, which I can't seem to be able to configure in the authenticator component (although, signUp also presents the same issue, so in fact I doubt it's that).

@timngyn
Copy link
Member

timngyn commented Jul 12, 2024

Hi @Catazza, just to clarify to make sure I'm understanding correctly, when you say local builds, you're using the preview build from EAS right?

Have you also tried using this command npx expo run:ios --configuration Release or npx expo run:android --variant release? Taken from here: https://docs.expo.dev/more/expo-cli/#compiling-android

@Catazza
Copy link
Author

Catazza commented Jul 12, 2024

Hi @timngyn nice shout on trying the release variants from the CLI. I have done that (I used npx expo run:ios --configuration Release), I still see the same error, but now I can see the logs in the console:

[RemoteTextInput] -[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:]  perform input operation
requires a valid sessionID

@reesscot
Copy link
Contributor

reesscot commented Jul 12, 2024

@Catazza Can you also share your amplifyconfiguration.json file (with any sensitive pieces redacted)? It

Yes, any build logs you have would be helpful as well.

It also looks like you are overriding the loginMechanism and signUpAttributes. Do you get the same errors if you leave them off and let the configuration file determine your login type based on your Cognito settings?

@Catazza
Copy link
Author

Catazza commented Jul 12, 2024

Hi @timngyn @reesscot so to provide further details: I have also tried the "bare" signIn function outside of the component, and we still get the same behaviour (i.e. it does work in the dev app version but not in the release one created with npx expo run:ios --configuration Release). I have also enabled the plain USER_PASSWORD_AUTH auth flow, but that also does not work.

I might open an issue in the Amplify-js repo, as it's not just a UI component issue, also the bare amplify method does not work. WDYT?

Here's the auth part of the amplify_outputs.json by the way:

{
  "auth": {
    "user_pool_id": "xxxx",
    "aws_region": "eu-central-1",
    "user_pool_client_id": "xxxx",
    "identity_pool_id": "xxxx",
    "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
  }
}

@timngyn
Copy link
Member

timngyn commented Jul 12, 2024

Hey @Catazza, thanks so much for trying that out. That makes sense to open the issue in Amplify JS. I can transfer the issue over to their repo (so you don't have to open a new ticket)

@timngyn timngyn transferred this issue from aws-amplify/amplify-ui Jul 12, 2024
@timngyn timngyn removed their assignment Jul 12, 2024
@cwomack cwomack added the transferred This issue was transferred from another Amplify project label Jul 12, 2024
@cwomack cwomack self-assigned this Jul 12, 2024
@cwomack
Copy link
Member

cwomack commented Jul 12, 2024

@Catazza, thanks for opening this issue and we'll investigate this/attempt to reproduce on our side. In the mean time, are you seeing any errors or logs (either screenshots or text) that can be shared on the release build?

@cwomack cwomack added Auth Related to Auth components/category question General question pending-response and removed Authenticator pending-triage Issue is pending triage pending-response labels Jul 12, 2024
@Catazza
Copy link
Author

Catazza commented Jul 12, 2024

@Catazza, thanks for opening this issue and we'll investigate this/attempt to reproduce on our side. In the mean time, are you seeing any errors or logs (either screenshots or text) that can be shared on the release build?

Hi @cwomack I can't see anything beyond the screenshot I shared in the issue description. If I use the bare signIn method, I can't see anything at all (no logs no errors). I'll try setting up Sentry to see if I have any better luck there

@Catazza
Copy link
Author

Catazza commented Jul 12, 2024

@cwomack build logs when I run npx expo run:ios --configuration Release don't say much:

› Planning build
› Executing react-native Pods/hermes-engine » [CP-User] [Hermes] Replace Hermes for the right configuration, if needed
› Executing react-native Pods/React-Fabric » [CP-User] [RN]Check rncore
› Executing expo-constants Pods/EXConstants » [CP-User] Generate app.config for prebuilt Constants.manifest
› Executing myapp » [Expo] Configure project
› Executing myapp » Bundle React Native code and images
    Bundler cache is empty, rebuilding (this may take a minute)
› Executing myapp » [CP] Copy Pods Resources
› Signing   myapp » myapp.app
› Build Succeeded

› 0 error(s), and 1 warning(s)

Starting Metro Bundler
Waiting on http://localhost:8081
› Installing on iPhone 15 Pro Max
› Opening on iPhone 15 Pro Max (com.myappai.myapp)
› Opening exp+myapp://expo-development-client/?url=http%3A%2F%2F192.168.1.42%3A8081 on iPhone 15 Pro Max

› Logs for your project will appear below.

[CoreFoundation] AddInstanceForFactory: No factory registered for id <CFUUID
xxxx> xxxxx

Cloudtrail event:

{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "Unknown",
        "principalId": "Anonymous"
    },
    "eventTime": "2024-07-12T19:21:42Z",
    "eventSource": "cognito-idp.amazonaws.com",
    "eventName": "InitiateAuth",
    "awsRegion": "eu-central-1",
    "sourceIPAddress": "1234",
    "userAgent": "myapp/1 CFNetwork/1474 Darwin/22.6.0",
    "requestParameters": {
        "authFlow": "USER_PASSWORD_AUTH",
        "authParameters": "HIDDEN_DUE_TO_SECURITY_REASONS",
        "clientId": "xxxx"
    },
    "responseElements": {
        "challengeParameters": "HIDDEN_DUE_TO_SECURITY_REASONS",
        "authenticationResult": {
            "accessToken": "HIDDEN_DUE_TO_SECURITY_REASONS",
            "expiresIn": 3600,
            "tokenType": "Bearer",
            "refreshToken": "HIDDEN_DUE_TO_SECURITY_REASONS",
            "idToken": "HIDDEN_DUE_TO_SECURITY_REASONS"
        }
    },
    "additionalEventData": {
        "sub": "xxxx"
    },
    "requestID": "e84e5394-62f0-47ab-88ee-ef2e4c548e0b",
    "eventID": "7360e3c0-ec1e-4365-9589-b63994091ce2",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "12345678",
    "eventCategory": "Management",
    "tlsDetails": {
        "tlsVersion": "TLSv1.3",
        "cipherSuite": "TLS_AES_128_GCM_SHA256",
        "clientProvidedHostHeader": "cognito-idp.eu-central-1.amazonaws.com"
    }
}

I am now going to investigate perhaps permission issues

@HuiSF
Copy link
Member

HuiSF commented Jul 13, 2024

Hi @Catazza Thank you for provide detailed information helping with the triaging process.

I created a minimum Expo app that invokes the Amplify signIn() API without the Authenticator to isolate the issue. I created a production build use the Expo EAS build CLI and installed the app to an iPhone device. From testing I don't see any issues calling signIn(), where I can sign in an end user, and subsequently get the user session via calling fetchAuthSession.

From your screenshots in the original post, I saw "Network error" so I suspect the network request generated by signIn or signUp call didn't go through. Could you double check whether your native app has any network related configuration that's build scheme specific?

In your last comment though, the Cloudtrail log indicates that there was a successful sign in and tokens were returned to the client. Can you confirm whether this event was triggered by clicking the sign in button in your app?

@stewartmoreland
Copy link

I've encountered a similar issue. While the Expo dev client functions as expected, production build fail to render the children components as expected. The authenticator component allows sign up & sign in but after returning session information, the app content refuses to load. No visible faults when streaming log data in Console.

@github-actions github-actions bot added the pending-maintainer-response Issue is pending a response from the Amplify team. label Sep 14, 2024
@ashika112
Copy link
Member

Hi @Catazza , wondering if you have had the chance to look into this request from Hui?

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending a response from the Amplify team. label Oct 8, 2024
@ashika112 ashika112 added the pending-community-response Issue is pending a response from the author or community. label Oct 8, 2024
@cwomack
Copy link
Member

cwomack commented Oct 22, 2024

Closing this issue as we have not heard back from you. If you are still experiencing this, please feel free to reply back and provide any information previously requested and we'd be happy to re-open the issue.

We'll also reference the following docs that will hopefully help clear up what to do here if anyone else comes across this, which may be tied to how EAS is configured when using Expo CLI with React Native:

Thank you!

@cwomack cwomack closed this as completed Oct 22, 2024
@github-actions github-actions bot removed the pending-community-response Issue is pending a response from the author or community. label Oct 22, 2024
@upp22
Copy link

upp22 commented Oct 28, 2024

@Catazza wondering how you went with this? Running a new project with Amplify Gen 2 and thinking if using the Authenticator will be a time sink...

@github-actions github-actions bot added the pending-maintainer-response Issue is pending a response from the Amplify team. label Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Auth Related to Auth components/category pending-maintainer-response Issue is pending a response from the Amplify team. question General question transferred This issue was transferred from another Amplify project
Projects
None yet
Development

No branches or pull requests

8 participants