在用户文档上使用firebase快照的React上下文



由于某些原因,在我的函数"login"中,我的"currentUser"State总是返回null。我要做的是在用户登录时对用户文档设置快照。

我也不确定是否可以在这样的状态下保存退订函数但这是一个问题,我还没有机会使用

我的上下文组件是这样的:

import React, { useContext, useState, useEffect } from 'react'
import { auth, db } from '../init/firebase'
const AuthContext = React.createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState("")
const [loading, setLoading] = useState(true)
// User firebase doc init
const [userDoc, setUserDoc] = useState({
loaded: false,
data: [],
})
const [firebaseUnsubscriber, setFirebaseUnsubscriber] = useState(null);
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password)
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password).then(() => {
// The problem here is that "currentUser" is always null
const firebaseUnsubscriber = db.collection("users").doc(currentUser.uid).onSnapshot((doc) => {
setUserDoc({
loaded: true,
data: doc.data(),
})
});

setFirebaseUnsubscriber(firebaseUnsubscriber);
})
}
function logout() {
return auth.signOut().then(() => {
firebaseUnsubscriber();
})
}
useEffect(() => {
const unsubscriber = auth.onAuthStateChanged((user) => {
setCurrentUser(user)
setLoading(false)
})
return unsubscriber
}, [])
const value = {
currentUser,
userDoc,
login,
signup,
logout,
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}

这只是时间问题。当你调用setCurrentUser或其他从useState()调用返回的setter时,你不改变变量的当前值——而是设置下一个变量的值——直到React决定需要渲染器时才会使用。

不要在signInWithEmailAndPassword()then处理程序中使用currentUser,而应该使用承诺中包含的UserCredential对象。

function login(email, password) {
return auth
.signInWithEmailAndPassword(email, password)
.then((userCredential) => {
const firebaseUnsubscriber = db.collection("users")
.doc(userCredential.user.uid)
.onSnapshot((doc) => {
setUserDoc({
loaded: true,
data: doc.data(),
})
});

setFirebaseUnsubscriber(firebaseUnsubscriber);
});
}

现在,虽然上面的代码可以解决您的问题,但仍然存在许多问题:

  • setFirebaseUnsubscriber在状态下存储一个退订函数,这将导致一个呈现,这意味着应该调用退订者,这导致一个新的退订者被存储,这意味着应该调用退订者,这导致…(用户数据部分应该在自己的useEffect中)
  • 检索用户数据的错误被静默忽略
  • 新创建的用户将没有任何用户数据要加载(并且data将被设置为undefined而不是[],就像初始状态一样)
  • 退出的用户没有清除他们的数据
  • 你的currentUser状态变量的类型是User | "" | null。用户User | null(建议使用loading)或User | null | undefined
  • 当前用户的加载状态不暴露给上下文消费者
  • 当前代码利用should-be-considered-deprecated名称空间v8 Web SDK——如果编写新的代码,您应该使用模块化v9 Web SDK。

要解决这些问题的方法有点复杂,但很健壮,请查看此答案及其FirebaseAuthUserContext版本。在撰写本文时,它使用v8 SDK,但我将在将来将其更新为v9。

相关内容

  • 没有找到相关文章

最新更新