Fix nextjs console error by not loading from localstorage immedately. Use layout effect instead.
This commit is contained in:
parent
96791e11a5
commit
2c9f8e00bf
|
@ -1,9 +1,11 @@
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useLayoutEffect, useState } from 'react'
|
||||||
import { getCachedUser, listenForLogin, listenForUser, User } from '../lib/firebase/users'
|
import { listenForLogin, listenForUser, User } from '../lib/firebase/users'
|
||||||
|
|
||||||
export const useUser = () => {
|
export const useUser = () => {
|
||||||
const [user, setUser] = useState<User | null | undefined>(getCachedUser())
|
const [user, setUser] = useState<User | null | undefined>(undefined)
|
||||||
useEffect(() => listenForLogin(setUser), [])
|
|
||||||
|
// Use layout effect to trigger re-render before first paint.
|
||||||
|
useLayoutEffect(() => listenForLogin(setUser), [])
|
||||||
|
|
||||||
const userId = user?.id
|
const userId = user?.id
|
||||||
|
|
||||||
|
|
|
@ -61,30 +61,34 @@ export function listenForUser(userId: string, setUser: (user: User) => void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const CACHED_USER_KEY = 'CACHED_USER_KEY'
|
const CACHED_USER_KEY = 'CACHED_USER_KEY'
|
||||||
export function listenForLogin(onUser: (_user: User | null) => void) {
|
export function listenForLogin(onUser: (user: User | null) => void) {
|
||||||
return onAuthStateChanged(auth, async (user) => {
|
const cachedUser = localStorage.getItem(CACHED_USER_KEY)
|
||||||
if (user) {
|
onUser(cachedUser ? JSON.parse(cachedUser) : null)
|
||||||
let fetchedUser = await getUser(user.uid)
|
|
||||||
if (!fetchedUser) {
|
return onAuthStateChanged(auth, async (fbUser) => {
|
||||||
|
if (fbUser) {
|
||||||
|
let user = await getUser(fbUser.uid)
|
||||||
|
if (!user) {
|
||||||
// User just created an account; save them to our database.
|
// User just created an account; save them to our database.
|
||||||
fetchedUser = {
|
user = {
|
||||||
id: user.uid,
|
id: fbUser.uid,
|
||||||
name: user.displayName || 'Default Name',
|
name: fbUser.displayName || 'Default Name',
|
||||||
username: user.displayName?.replace(/\s+/g, '') || 'DefaultUsername',
|
username:
|
||||||
avatarUrl: user.photoURL || '',
|
fbUser.displayName?.replace(/\s+/g, '') || 'DefaultUsername',
|
||||||
email: user.email || 'default@blah.com',
|
avatarUrl: fbUser.photoURL || '',
|
||||||
|
email: fbUser.email || 'default@blah.com',
|
||||||
balance: STARTING_BALANCE,
|
balance: STARTING_BALANCE,
|
||||||
// TODO: use Firestore timestamp?
|
// TODO: use Firestore timestamp?
|
||||||
createdTime: Date.now(),
|
createdTime: Date.now(),
|
||||||
lastUpdatedTime: Date.now(),
|
lastUpdatedTime: Date.now(),
|
||||||
}
|
}
|
||||||
await setUser(user.uid, fetchedUser)
|
await setUser(fbUser.uid, user)
|
||||||
}
|
}
|
||||||
onUser(fetchedUser)
|
onUser(user)
|
||||||
|
|
||||||
// Persist to local storage, to reduce login blink next time.
|
// Persist to local storage, to reduce login blink next time.
|
||||||
// Note: Cap on localStorage size is ~5mb
|
// Note: Cap on localStorage size is ~5mb
|
||||||
localStorage.setItem(CACHED_USER_KEY, JSON.stringify(fetchedUser))
|
localStorage.setItem(CACHED_USER_KEY, JSON.stringify(user))
|
||||||
} else {
|
} else {
|
||||||
// User logged out; reset to null
|
// User logged out; reset to null
|
||||||
onUser(null)
|
onUser(null)
|
||||||
|
@ -93,13 +97,6 @@ export function listenForLogin(onUser: (_user: User | null) => void) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCachedUser() {
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
const cachedUser = localStorage.getItem(CACHED_USER_KEY)
|
|
||||||
return cachedUser ? (JSON.parse(cachedUser) as User) : undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function firebaseLogin() {
|
export async function firebaseLogin() {
|
||||||
const provider = new GoogleAuthProvider()
|
const provider = new GoogleAuthProvider()
|
||||||
signInWithPopup(auth, provider)
|
signInWithPopup(auth, provider)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user