Skip to content

Commit a119c2a

Browse files
committedNov 7, 2022
[auth] Add onIdToken. Fixes #223
1 parent b5b2955 commit a119c2a

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed
 

‎auth/README.md

+68-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useAuthState } from 'react-firebase-hooks/auth';
1111
List of Auth hooks:
1212

1313
- [useAuthState](#useauthstate)
14+
- [useIdToken](#useidtoken)
1415
- [useCreateUserWithEmailAndPassword](#usecreateuserwithemailandpassword)
1516
- [useSignInWithEmailAndPassword](#usesigninwithemailandpassword)
1617
- [useSignInWithApple](#usesigninwithapple)
@@ -35,7 +36,7 @@ List of Auth hooks:
3536
const [user, loading, error] = useAuthState(auth, options);
3637
```
3738

38-
Retrieve and monitor the authentication state from Firebase.
39+
Retrieve and monitor the authentication state from Firebase. Uses `auth.onAuthStateChanged` so is only triggered when a user signs in or signs out. See [useIdToken](#useidtoken) if you need to monitor token changes too.
3940

4041
The `useAuthState` hook takes the following parameters:
4142

@@ -95,6 +96,72 @@ const CurrentUser = () => {
9596
};
9697
```
9798

99+
### useIdToken
100+
101+
```js
102+
const [user, loading, error] = useIdToken(auth, options);
103+
```
104+
105+
Retrieve and monitor changes to the ID token from Firebase. Uses `auth.onIdTokenChanged` so includes when a user signs in, signs out or token refresh events.
106+
107+
The `useIdToken` hook takes the following parameters:
108+
109+
- `auth`: `auth.Auth` instance for the app you would like to monitor
110+
- `options`: (optional) `Object with the following parameters:
111+
- `onUserChanged`: (optional) function to be called with `auth.User` each time the user changes. This allows you to do things like load custom claims.
112+
113+
Returns:
114+
115+
- `user`: The `auth.UserCredential` if logged in, or `null` if not
116+
- `loading`: A `boolean` to indicate whether the authentication state is still being loaded
117+
- `error`: Any `AuthError` returned by Firebase when trying to load the user, or `undefined` if there is no error
118+
119+
#### If you are registering or signing in the user for the first time consider using [useCreateUserWithEmailAndPassword](#usecreateuserwithemailandpassword), [useSignInWithEmailAndPassword](#usesigninwithemailandpassword)
120+
121+
#### Full Example
122+
123+
```js
124+
import { getAuth, signInWithEmailAndPassword, signOut } from 'firebase/auth';
125+
import { useIdToken } from 'react-firebase-hooks/auth';
126+
127+
const auth = getAuth(firebaseApp);
128+
129+
const login = () => {
130+
signInWithEmailAndPassword(auth, 'test@test.com', 'password');
131+
};
132+
const logout = () => {
133+
signOut(auth);
134+
};
135+
136+
const CurrentUser = () => {
137+
const [user, loading, error] = useIdToken(auth);
138+
139+
if (loading) {
140+
return (
141+
<div>
142+
<p>Initialising User...</p>
143+
</div>
144+
);
145+
}
146+
if (error) {
147+
return (
148+
<div>
149+
<p>Error: {error}</p>
150+
</div>
151+
);
152+
}
153+
if (user) {
154+
return (
155+
<div>
156+
<p>Current User: {user.user.email}</p>
157+
<button onClick={logout}>Log out</button>
158+
</div>
159+
);
160+
}
161+
return <button onClick={login}>Log in</button>;
162+
};
163+
```
164+
98165
### useCreateUserWithEmailAndPassword
99166

100167
```js

‎auth/useIdToken.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Auth, onIdTokenChanged, User } from 'firebase/auth';
2+
import { useEffect } from 'react';
3+
import { LoadingHook, useLoadingValue } from '../util/dist/util';
4+
5+
export type IdTokenHook = LoadingHook<User | null, Error>;
6+
7+
type IdTokenOptions = {
8+
onUserChanged?: (user: User | null) => Promise<void>;
9+
};
10+
11+
export default (auth: Auth, options?: IdTokenOptions): IdTokenHook => {
12+
const { error, loading, setError, setValue, value } = useLoadingValue<
13+
User | null,
14+
Error
15+
>(() => auth.currentUser);
16+
17+
useEffect(() => {
18+
const listener = onIdTokenChanged(
19+
auth,
20+
async (user) => {
21+
if (options?.onUserChanged) {
22+
// onUserChanged function to process custom claims on any other trigger function
23+
try {
24+
await options.onUserChanged(user);
25+
} catch (e) {
26+
setError(e as Error);
27+
}
28+
}
29+
setValue(user);
30+
},
31+
setError
32+
);
33+
34+
return () => {
35+
listener();
36+
};
37+
}, [auth]);
38+
39+
return [value, loading, error];
40+
};

0 commit comments

Comments
 (0)
Please sign in to comment.