auth0 / react-native-auth0

React Native toolkit for Auth0 API
https://auth0.com
MIT License
492 stars 209 forks source link

Provide a way to update the stored user in the useAuth0 hook #572

Closed haagOS closed 1 year ago

haagOS commented 1 year ago

Describe the problem you'd like to have solved

I have a use case where the user is required to verify their email before being able to perform an action.

Im am using the useAuth0() hook because hooks are great. On app start I check for credentials and the user. If the èmail_verified flag is false, I will show a certain screen and periodically call the /userinfo endpoint to see if, in the meantime, the user verified their email.

Now the problem is, that though the flag will be true as soon as the user verified their email, on the next app start the same screen will be shown again, because the updated user info never made it's way into the Auth0Provider or the internal storing mechanism (credential manager?).

The same problem exists for all the other user properties.

Describe the ideal solution

something like the following would be great:

const { user, fetchUserInfo } = useAuth0();

useEffect(() => {
  const interval = setInterval(() => {
      // may or may not be a promise.
      // updates the internally stored user
      fetchUserInfo();
    }, timeout);
    return () => clearInterval(interval);
}, [fetchUserInfo])

if (user.email_verified) {
  // ready to go
}

Alternatives and current work-arounds

My current workaround is to store the user in my own persistent storage. This is far from ideal, because things can get out of sync easily and the hook kind of loses it's purpose (in this scenario).

Additional information, if any

SDK Version: 2.16.0

If there is interest in this feature, I am happy to provide a pull request.

Maybe related: #562

poovamraj commented 1 year ago

Hi @haagOS this is an interesting feature request. This makes me wonder whether we should provide a syncUserInfo() as a method in the hook and update the user object from there or just allow the developer to update the user object directly.

I would like to receive more feedback from the community and my team on this.

poovamraj commented 1 year ago

Hi @haagOS we have got a PR on this issue where the user is updated when the credentials is received - https://github.com/auth0/react-native-auth0/pull/584. Would love to hear your feedback on this

haagOS commented 1 year ago

Hi @poovamraj. Looks promising.

However, one question:

getCredentials hook method now updates user state. This is important because when getting new credentials the ID token may be renewed, if renewed, the ID token's claims may now be different and so the user state (which is derived from these claims) should also be updated.

If a user's ID token changes in some way (meta data perhaps) and it going to be renewed (depends on expiresAt credentials value) then upon calling getCredentials - the user state should reflect the respective changes made to the ID token.

For my use case that means, that the ID token/ credentials (and therefore user.email_verified) gets renewed in case the ID token is about to expire. Is there a way to force the ID token renewal yet?

poovamraj commented 1 year ago

Great question. Yes, our plan is to provide a way to force refresh the tokens, that way the user object can be synced with the backend and will be immutable at the same time.

poovamraj commented 1 year ago

@haagOS since we already have a PR that updates user when credentials is refreshed - https://github.com/auth0/react-native-auth0/pull/584

And we have plans to provide option to force refresh in our next major version (slated soon). We will close this issue. This is in our backlog as SDK-3998.

raynox commented 6 months ago

Any update here? I think there is still no method to get or refresh the user. I have a following issue, when opening the app I need to decide whether I should display a verify email screen or redirect user to the app. So after registration when the user opens the app emailVerified field is false so an user gets redirected to the verify email screen. In the meanwhile the user confirms the email and refreshes the app. However emailVerified is still false, cause useAuth0 doesn't refresh the user. I can call getCredentials each time and when this transition happens it's going to work, cause there will be new user object with emailVerified as true and I can handle it in useEffect eg. However when user is still not verified the app is stuck, cause I don't when I should know that I refreshed credentials and the user and it's still not verified, cause there is no flag to handle that. isLoading only indicates whether the library is loaded, but not that user is being refreshed. So even after using getCredentials I get the same user and useEffect is not being triggered. It would help a lot if you simply add an async method getUser, which refreshes the object or perhaps getCredentials should return both the credentials and the new user object.

raynox commented 6 months ago

@poovamraj any update on the force refresh option? Or did you mean forceRefresh in getCredentials? The issue is it doesn't immediately provide the new user after calling getCredentials. The new user is not returned by the method and it's only accessible as a prop from useAuth0 hook, however the update might take a while and nothing indicates when user is refetched. Please look above for a more specific example of the issue.

mikehuebner commented 4 months ago

With @raynox on this one, the documentation around forceRefresh is not clear and I'm unsure what to do if the function returns undefined. My immediate assumption is the user couldn't be logged in or refreshed with the current token, therefore force the logout?

Also having an issue with requireLocalAuthentication just not doing anything at all.