Can anyone help me with this please with this useEffect in React? I am updating custom claims in firebase auth via a firestore document called user_claims. In here it has a user role. Instead of waiting an hour for the token to be refreshed....I want to refresh it as soon as I make a change to the user_claims collection. Based on the below I am getting the error: Unhandled Rejection (TypeError): Cannot read property 'getIdTokenResult' of undefined
Have I put my listeners in the wrong order or should I have two useEffects? Not sure what I need to do and would appreciate guidance. I want to get the user role - in real-time into the AuthContext for use throughout the app.
thanks all in advance for your help and guidance, as always.
import React, { useEffect, useState, createContext } from 'react'
import {firebase, firestore} from './firebase'
export const AuthContext = createContext()
export const AuthProvider = ({ children }) => {
const auth=firebase.auth();
const [currentUser, setCurrentUser] = useState();
const [error, setError] = useState();
useEffect(() => {
async function reportAdminStatus() {
const result = await currentUser.getIdTokenResult(false)
const isAdmin = result.claims.isAdmin
if (isAdmin) {
console.log("Custom claims say I am an admin!")
}
else {
console.log("Custom claims say I am not an admin.")
}
}
auth.onIdTokenChanged(user => {
if (user) {
console.log(`new ID token for ${user.uid}`)
setCurrentUser(user)
reportAdminStatus()
}
})
auth.onAuthStateChanged(async (user) => {
function listenToClaims() {
firestore
.collection('user_claims')
.doc(currentUser.uid)
.onSnapshot(onNewClaims)
}
let synced
function onNewClaims(snapshot) {
const data = snapshot.data()
console.log('New claims doc\n', data)
if (data._synced) {
if (synced &&
!data._synced.isEqual(synced)) {
// Force a refresh of the user's ID token
console.log('Refreshing token')
currentUser.getIdToken(true)
}
synced = data._synced
}
}
if (user) {
try {
const idTokenResult = await user.getIdTokenResult();
setCurrentUser({...user, role: idTokenResult.claims.role, isAdmin: idTokenResult.claims.isAdmin, group: idTokenResult.claims.group });
setError(undefined);
listenToClaims();
reportAdminStatus();
} catch (e) {
setError(e);
}
} else {
setCurrentUser(undefined);
}
});
return [currentUser, error]
}, []);
return (
<AuthContext.Provider value={{ currentUser }}>
{children}
</AuthContext.Provider>
)
}