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 { getCachedUser, listenForLogin, listenForUser, User } from '../lib/firebase/users'
|
||||
import { useEffect, useLayoutEffect, useState } from 'react'
|
||||
import { listenForLogin, listenForUser, User } from '../lib/firebase/users'
|
||||
|
||||
export const useUser = () => {
|
||||
const [user, setUser] = useState<User | null | undefined>(getCachedUser())
|
||||
useEffect(() => listenForLogin(setUser), [])
|
||||
const [user, setUser] = useState<User | null | undefined>(undefined)
|
||||
|
||||
// Use layout effect to trigger re-render before first paint.
|
||||
useLayoutEffect(() => listenForLogin(setUser), [])
|
||||
|
||||
const userId = user?.id
|
||||
|
||||
|
|
|
@ -61,30 +61,34 @@ export function listenForUser(userId: string, setUser: (user: User) => void) {
|
|||
}
|
||||
|
||||
const CACHED_USER_KEY = 'CACHED_USER_KEY'
|
||||
export function listenForLogin(onUser: (_user: User | null) => void) {
|
||||
return onAuthStateChanged(auth, async (user) => {
|
||||
if (user) {
|
||||
let fetchedUser = await getUser(user.uid)
|
||||
if (!fetchedUser) {
|
||||
export function listenForLogin(onUser: (user: User | null) => void) {
|
||||
const cachedUser = localStorage.getItem(CACHED_USER_KEY)
|
||||
onUser(cachedUser ? JSON.parse(cachedUser) : null)
|
||||
|
||||
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.
|
||||
fetchedUser = {
|
||||
id: user.uid,
|
||||
name: user.displayName || 'Default Name',
|
||||
username: user.displayName?.replace(/\s+/g, '') || 'DefaultUsername',
|
||||
avatarUrl: user.photoURL || '',
|
||||
email: user.email || 'default@blah.com',
|
||||
user = {
|
||||
id: fbUser.uid,
|
||||
name: fbUser.displayName || 'Default Name',
|
||||
username:
|
||||
fbUser.displayName?.replace(/\s+/g, '') || 'DefaultUsername',
|
||||
avatarUrl: fbUser.photoURL || '',
|
||||
email: fbUser.email || 'default@blah.com',
|
||||
balance: STARTING_BALANCE,
|
||||
// TODO: use Firestore timestamp?
|
||||
createdTime: 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.
|
||||
// Note: Cap on localStorage size is ~5mb
|
||||
localStorage.setItem(CACHED_USER_KEY, JSON.stringify(fetchedUser))
|
||||
localStorage.setItem(CACHED_USER_KEY, JSON.stringify(user))
|
||||
} else {
|
||||
// User logged out; reset to 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() {
|
||||
const provider = new GoogleAuthProvider()
|
||||
signInWithPopup(auth, provider)
|
||||
|
|
Loading…
Reference in New Issue
Block a user