Skip to content

Commit ced3a0b

Browse files
docs: add FAQ on refreshing user profile after server-side changes (#1451)
1 parent 906dac2 commit ced3a0b

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

FAQ.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
15. [How do I know if my tokens are using DPoP?](#15-how-do-i-know-if-my-tokens-are-using-dpop)
1818
16. [What happens if I disable DPoP after enabling it?](#16-what-happens-if-i-disable-dpop-after-enabling-it)
1919
17. [Why does the app hang or freeze during Social Login (Google, Facebook, etc.)?](#17-why-does-the-app-hang-or-freeze-during-social-login-google-facebook-etc)
20+
18. [How do I refresh the user profile (e.g. `emailVerified`) after it changes on the server?](#18-how-do-i-refresh-the-user-profile-eg-emailverified-after-it-changes-on-the-server)
2021

2122
## 1. How can I have separate Auth0 domains for each environment on Android?
2223

@@ -937,3 +938,87 @@ plutil -p ios/YourApp/Info.plist | grep -A 5 "CFBundleURLSchemes"
937938
```
938939
939940
> **Note**: The SDK automatically lowercases your package/bundle identifier. If it's `com.example.MyApp`, the callback URL uses `com.example.myapp`.
941+
942+
## 18. How do I refresh the user profile (e.g. `emailVerified`) after it changes on the server?
943+
944+
A common scenario is email verification: a user signs up, receives a verification email, clicks the link, and returns to the app. However, the `user` object from `useAuth0()` still shows `emailVerified: false` because the user state is derived from the ID token claims, which are cached locally.
945+
946+
To get the updated user profile, you need to force-refresh the credentials so the SDK fetches a new ID token with the latest claims from Auth0.
947+
948+
### Prerequisites
949+
950+
1. **Include `offline_access` in the scope during the initial login.** This is required because `forceRefresh` uses the refresh token to obtain new credentials. Without it, calling `getCredentials` with `forceRefresh: true` will fail with a `NO_REFRESH_TOKEN` error.
951+
952+
2. **Use `forceRefresh: true` when calling `getCredentials`.** This forces the SDK to call the `/oauth/token` endpoint and fetch a new ID token with up-to-date claims.
953+
954+
### Step-by-Step Example
955+
956+
**Step 1: Log in with `offline_access` scope**
957+
958+
```tsx
959+
import { useAuth0 } from 'react-native-auth0';
960+
961+
function LoginScreen() {
962+
const { authorize } = useAuth0();
963+
964+
const handleLogin = async () => {
965+
await authorize({
966+
scope: 'openid profile email offline_access', // offline_access is required
967+
});
968+
};
969+
970+
// ...
971+
}
972+
```
973+
974+
**Step 2: After the user verifies their email (or any server-side profile change), force-refresh credentials**
975+
976+
```tsx
977+
import { useAuth0 } from 'react-native-auth0';
978+
979+
function VerifyEmailScreen() {
980+
const { user, getCredentials } = useAuth0();
981+
982+
const refreshUserProfile = async () => {
983+
try {
984+
await getCredentials(
985+
'openid profile email offline_access',
986+
undefined, // minTtl
987+
undefined, // parameters
988+
true // forceRefresh — forces a new token request
989+
);
990+
// After this call, the `user` object from useAuth0() will be updated
991+
// with the latest claims (e.g., emailVerified: true)
992+
} catch (error) {
993+
console.error('Failed to refresh credentials:', error);
994+
}
995+
};
996+
997+
if (user?.emailVerified) {
998+
return <Text>Email verified! You're all set.</Text>;
999+
}
1000+
1001+
return (
1002+
<View>
1003+
<Text>Please verify your email, then tap the button below.</Text>
1004+
<Button title="I've verified my email" onPress={refreshUserProfile} />
1005+
</View>
1006+
);
1007+
}
1008+
```
1009+
1010+
### How It Works
1011+
1012+
1. `getCredentials` with `forceRefresh: true` uses the stored refresh token to call the Auth0 `/oauth/token` endpoint.
1013+
2. Auth0 returns a new ID token whose claims reflect the current server-side user profile.
1014+
3. The SDK parses the new ID token and updates the `user` object in the `Auth0Provider` context.
1015+
4. Any component consuming `useAuth0()` will re-render with the updated user data.
1016+
1017+
### Common Errors
1018+
1019+
| Error | Cause | Fix |
1020+
| --------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
1021+
| `NO_REFRESH_TOKEN` | `offline_access` was not included in the `authorize()` scope | Add `offline_access` to the scope in the **initial** `authorize()` call. The user may need to log out and log in again. |
1022+
| `getCredentials` promise never resolves | Missing refresh token or network issue | Ensure `offline_access` is included during login, and check network connectivity. |
1023+
1024+
> **Note**: This behavior differs from the web SDK (`@auth0/auth0-spa-js`), where token refresh is handled automatically via silent authentication using iframes. On native platforms (iOS/Android), a refresh token is explicitly required.

0 commit comments

Comments
 (0)