我在 firebase 中创建用户时遇到同步错误。本质上,当创建新用户时,我的注册组件中会调用以下函数:
const handleSignUp = async () => {
// Create the user with email and password
const userCredential = await auth.createUserWithEmailAndPassword(email, password);
await userCredential.user.updateProfile({
displayName: name,
});
// User is signed up with the name added to their profile and Firestore document.
// You can handle redirection or any other logic here.
}
然后,在我的 app.js 中,我有一个
useEffect
监听身份验证状态的更改。当用户登录时,它应该调用 syncUser
,它会在我的 Firestore 数据库中为该用户创建一个文档。然而,这些 useEffect
似乎是在登录中调用 updateProfile
之前调用的。因此,当调用它时,user.displayName
是 null
。
useEffect(() => {
const unregisterAuthObserver = auth.onAuthStateChanged(async (user) => {
if (user) {
if(user.displayName) // A: Sometimes this is null in the beginning
{
await syncUsers(user); // B
}
setCurrentUser(user);
} else {
setCurrentUser(null);
}
});
return () => unregisterAuthObserver();
我尝试了几种不同的解决方案。一种是如上面所见,在调用
user.displayName
之前检查 syncUsers
是否不为空。然而,这样做的效果只是阻止文档被创建,因为 useEffect
只被调用一次。
您的
useEffect
处理程序调用 onAuthStateChanged
,这会在用户的身份验证状态更改时触发。当用户登录时,身份验证状态会发生变化,因此当您调用 createUserWithEmailAndPassword
时。但是,更新当前用户的个人资料需要他们已经登录,因此调用 updateProfile
不会导致身份验证 state 更改。
您需要使用另一种/附加机制来触发您的代码,例如在调用
syncUsers
完成后调用 updateProfile
。
您还可以监听
onIdTokenChanged
,只要用户的个人资料在客户端中发生更改,就会调用该函数。这可能需要长达一个小时的时间,因为 ID 令牌不会自动刷新以远程更改用户配置文件,但值得测试它在您的情况下的作用。