Some changes to make auth better (#846)

* Handle the case where a user is surprisingly not in the DB

* Only set referral info on user after creation

* More reliably cache current user info in local storage

* Don't jam username stuff into user listener hook
This commit is contained in:
Marshall Polaris 2022-09-02 19:39:27 -07:00 committed by GitHub
parent e924061c54
commit 8318621d51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -67,6 +67,16 @@ export function AuthProvider(props: {
} }
}, [setAuthUser, serverUser]) }, [setAuthUser, serverUser])
useEffect(() => {
if (authUser != null) {
// Persist to local storage, to reduce login blink next time.
// Note: Cap on localStorage size is ~5mb
localStorage.setItem(CACHED_USER_KEY, JSON.stringify(authUser))
} else {
localStorage.removeItem(CACHED_USER_KEY)
}
}, [authUser])
useEffect(() => { useEffect(() => {
return onIdTokenChanged( return onIdTokenChanged(
auth, auth,
@ -77,17 +87,13 @@ export function AuthProvider(props: {
if (!current.user || !current.privateUser) { if (!current.user || !current.privateUser) {
const deviceToken = ensureDeviceToken() const deviceToken = ensureDeviceToken()
current = (await createUser({ deviceToken })) as UserAndPrivateUser current = (await createUser({ deviceToken })) as UserAndPrivateUser
setCachedReferralInfoForUser(current.user)
} }
setAuthUser(current) setAuthUser(current)
// Persist to local storage, to reduce login blink next time.
// Note: Cap on localStorage size is ~5mb
localStorage.setItem(CACHED_USER_KEY, JSON.stringify(current))
setCachedReferralInfoForUser(current.user)
} else { } else {
// User logged out; reset to null // User logged out; reset to null
setUserCookie(undefined) setUserCookie(undefined)
setAuthUser(null) setAuthUser(null)
localStorage.removeItem(CACHED_USER_KEY)
} }
}, },
(e) => { (e) => {
@ -97,29 +103,32 @@ export function AuthProvider(props: {
}, [setAuthUser]) }, [setAuthUser])
const uid = authUser?.user.id const uid = authUser?.user.id
const username = authUser?.user.username
useEffect(() => { useEffect(() => {
if (uid && username) { if (uid) {
identifyUser(uid) identifyUser(uid)
setUserProperty('username', username) const userListener = listenForUser(uid, (user) => {
const userListener = listenForUser(uid, (user) => setAuthUser((currAuthUser) =>
setAuthUser((authUser) => { currAuthUser && user ? { ...currAuthUser, user } : null
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
return { ...authUser!, user: user! }
})
) )
const privateUserListener = listenForPrivateUser(uid, (privateUser) => {
setAuthUser((authUser) => {
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
return { ...authUser!, privateUser: privateUser! }
}) })
const privateUserListener = listenForPrivateUser(uid, (privateUser) => {
setAuthUser((currAuthUser) =>
currAuthUser && privateUser ? { ...currAuthUser, privateUser } : null
)
}) })
return () => { return () => {
userListener() userListener()
privateUserListener() privateUserListener()
} }
} }
}, [uid, username, setAuthUser]) }, [uid, setAuthUser])
const username = authUser?.user.username
useEffect(() => {
if (username != null) {
setUserProperty('username', username)
}
}, [username])
return ( return (
<AuthContext.Provider value={authUser}>{children}</AuthContext.Provider> <AuthContext.Provider value={authUser}>{children}</AuthContext.Provider>