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

Sign in user & get user object - Facebook & Google Login - AWS Amplify + React Native #4621

Closed
kevwang19 opened this issue Dec 22, 2019 · 10 comments

Comments

@kevwang19
Copy link

@kevwang19 kevwang19 commented Dec 22, 2019

Currently building a react native mobile app to use federated/social logins FB and Google with AWS Amplify. Followed some tutorials (mostly this one: https://dev.to/dabit3/the-complete-react-native-guide-to-user-authentication-with-the-amplify-framework-ib2) and amplify docs in setting up the login process, and am able to get to a certain point - will use FB login as an example.

  1. Used Auth.federatedSignIn({ provider: "Facebook" }) provided by amplify docs to a button on my login screen
  2. Can see on my Cognito user pool console that a user was created through FB
  3. Callback url on Cognito app client settings successfully redirects screen back to my mobile app
  4. At this point, used Auth.currentAuthenticatedUser() provided by amplify to try to get user, but keep on getting not authenticated / user not signed in

So basically my problem is that I can't get the user to be signed in after Cognito redirects to my react native app despite the user being created to the cognito user pool. I tried the hosted UI (would rather use my custom UI) solution as well, but getting the same issue of retrieving user after being redirected to my app, despite user having been created in user pool. Any help or insight appreciated!

@kevwang19 kevwang19 added the question label Dec 22, 2019
@Amplifiyer

This comment has been minimized.

Copy link
Contributor

@Amplifiyer Amplifiyer commented Dec 23, 2019

@kevwang19 can you provide your full sample app code here? Also have you tried using withOAuth HOC

@kernwig

This comment has been minimized.

Copy link

@kernwig kernwig commented Dec 24, 2019

Looks like the same problem I'm facing with an Angular app, so it's a core amplify-js bug. Upon sign-in with Google, the app reloads and I see the Cognito user information in local storage. Yet, Auth.authStateChange$ reports a state of “signedOut”. Explicitly requesting the current auth user also returns “No current user”. If I reload the page or navigate to the page with the amplify-authenticator component, then the state becomes “signedIn” and all is well.

Source code:
Call to federatedSignIn: https://github.com/kernwig/sqac-amplify/blob/468b8816aadb4c0ba5c1b80101d92909a8627b33/src/app/home/account.component.ts

Watch of Auth.authStateChange$: https://github.com/kernwig/sqac-amplify/blob/468b8816aadb4c0ba5c1b80101d92909a8627b33/src/app/services/user.service.ts

Live app: https://d3l0j9nusq7n6r.cloudfront.net/#/home/account

@kevwang19

This comment has been minimized.

Copy link
Author

@kevwang19 kevwang19 commented Dec 25, 2019

@Amplifiyer, below is my code for app.js. Created a switch nav between the rest of my app - AppNavigator and the Login screen:

const SwitchNav = createSwitchNavigator({
  Login: {
    screen: Login
  },
  AppNavigator: {
    screen: AppNavigator
  }
})

const AppContainer = createAppContainer(SwitchNav);

export default class App extends React.Component {
  componentDidMount() {
    this.checkAuth().then(()=> console.log('loaded compnonent, checked auth'))
  }
  checkAuth = async () => {
    try {
      await Auth.currentAuthenticatedUser()
      .then((user)=>{console.log(user)})
      .then(()=>{
        this.navigator.dispatch(
          NavigationActions.navigate({ routeName: 'AppNavigator' })
        )
      })

    } catch (err) {
      this.navigator.dispatch(
        NavigationActions.navigate({ routeName: 'Login' })
      )
      console.log('there is no user')
    }
  }

  render() {
    return (
      <AppContainer
        ref={nav => this.navigator = nav}
        onNavigationStateChange={this.checkAuth}
      />
    )
  }
}

On the login screen, I just have a button that has onPress={() => Auth.federatedSignIn({ provider: "Facebook" })}

If I press that button, it takes me to a safari browser to sign in through facebook, which then redirects through aws, then back to my app. It's just that when I get back to my app to check the authentication state, it still returns not authenticated. I'm thinking maybe it's because of the order in which the functions are called...perhaps the checkAuth functions are executing before the federated signin auth flow has a chance to return the signed in user.

If I really need to use AWS Cognito, I will try the HOC again. But in any case, I actually ended up using the react-native fbsdk instead, and got that to work instead of going through amazon cognito.
This example at the bottom works with FBSDK:
magus/react-native-facebook-login#176

@kevwang19

This comment has been minimized.

Copy link
Author

@kevwang19 kevwang19 commented Dec 25, 2019

I guess also I didn't quite understand the onNavigationStateChange part in the dev.to/dabit3 tutorial I mentioned earlier... seems to me that in order to call the function checkAuth, there needs to be a navigation state change, but wouldn't that be the result, not the trigger of the function?

@mynameisguy

This comment has been minimized.

Copy link

@mynameisguy mynameisguy commented Dec 25, 2019

I'm having the same issue in react-native app.
Users get created but after I log in, calling Auth.currentAuthenticatedUser(); return an error.
Regular sign in with username and password works (running Auth.currentAuthenticatedUser(); returns the user).

@Amplifiyer

This comment has been minimized.

Copy link
Contributor

@Amplifiyer Amplifiyer commented Dec 26, 2019

I'm thinking maybe it's because of the order in which the functions are called...perhaps the checkAuth functions are executing before the federated signin auth flow has a chance to return the signed in user.

@kevwang19 I believe that could be the root cause. Check the full React example here for capturing hub events. Ideally you will sign in and wait for the hub events to fire a signIn event which you can listen and then call checkUser. As an example, this is what HOC does https://github.com/aws-amplify/amplify-js/blob/master/packages/aws-amplify-react-native/src/Auth/withOAuth.js#L70

@kernwig

This comment has been minimized.

Copy link

@kernwig kernwig commented Dec 26, 2019

@Amplifiyer,
That the same problem happens with Angular and the solution you point to is pretty much what I'm unsuccessfully attempting. Either the same bug exists for both React and Angular, or in code shared by both.

It appears that this process only works if the login component is on the landing page after the redirect back to the application.

@Amplifiyer

This comment has been minimized.

Copy link
Contributor

@Amplifiyer Amplifiyer commented Dec 26, 2019

@kernwig, yes if you are using the HOCs then the landing page after the redirect should have the component since it's parsing the URL and updating the auth state. In your component, you can listen to the Hub events and after a successful signIn event, redirect the User to whatever landing page you desire.

kernwig pushed a commit to kernwig/sqac-amplify that referenced this issue Dec 27, 2019
- Detect federated sign-in and redirect user to account page.
- This fixes bug of sign-in not being detected - landing on the account page triggers Auth.authStateChange$
- See aws-amplify/amplify-js#4621
@kernwig

This comment has been minimized.

Copy link

@kernwig kernwig commented Dec 27, 2019

Okay, found two fixes based on your comments @Amplifiyer, both involving using the Hub to listen for signIn. I first use this as a direct analogue to monitoring Auth.authStateChange$. The Hub told me when a federated user signed in/out, and authStateChange$ for a user pool user. I still wanted to land on my accounts page though. So I changed it to navigate to the account page on Hub signIn event. Doing that caused Auth.authStateChange$ to trigger when the auth component rendered, so I just rely on that. Here's the code change: kernwig/sqac-amplify@8de758e

Note: The Hub doesn't play nice with Angular, thus the need to use NgZone directly.

@Amplifiyer

This comment has been minimized.

Copy link
Contributor

@Amplifiyer Amplifiyer commented Dec 31, 2019

@kernwig thanks for the update. @kevwang19 let us know if you are still facing any issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.