firebase 调用setDoc后,Firestore快照缺少字段

pgx2nnw8  于 2023-03-19  发布在  其他
关注(0)|答案(1)|浏览(176)

当用户登录到应用程序时,我正在创建一个用户文档。下面是用户单击登录按钮时运行的代码:

export function login() {
signInWithPopup(auth, provider).then(result => {
    const user = result.user;
    setDoc(doc(db, "users", user.uid), {
        name: user.displayName,
        email: user.email,
    }, {merge: true}); 

}).catch(error => {
    const errorCode = error.code;
})}

当用户希望向其任务列表中添加新任务时,将运行以下代码:

export function addTask(description: string) {
return new Promise(async (resolve, reject) => {
    if (!auth.currentUser) {
        //..
    } else {
        const userDoc = doc(db, "users", auth.currentUser.uid)
        await updateDoc(userDoc, {
            tasks: arrayUnion({ createdAt: (new Date()).toISOString(), description, done: false })
        })
        resolve(true);
    }
})}

当auth状态发生变化时,将执行以下代码,以便在用户登录后获取用户的任务。

function updateTasks(){
    getTasks().then(tasks => {
      setTasks(tasks);
    }).catch(err => {
      console.log(err);
      setTasks([]);
    })
  }

  useEffect(() => {
    onAuthStateChanged(auth, (user) => {
      if(user){
        setLoggedIn(true);
      } else setLoggedIn(false);
      updateTasks();
    })
  }, []);

到目前为止,一切都运行良好,但这里有一部分代码并没有像我预期的那样工作。
取任务代码:

export function getTasks() {
    return new Promise<Task[]>(async (resolve, reject) => {
        if(!auth.currentUser){
            reject(new Error("User is not logged in"));
        } else {
            const userDoc = doc(db, "users", auth.currentUser.uid);
            const docSnap = await getDoc(userDoc);
            const userData = docSnap.data() as User;
            console.log("userData", userData);
            resolve(userData.tasks);
          }
        }
    })
}

由于某种原因,它只返回对象的名称和电子邮件字段。(image1)

这是代码执行时数据库的状态。(image2)

wnavrhmk

wnavrhmk1#

setDoc和getDoc函数同时运行导致了该问题。我已通过使用自定义回调函数而不是onAuthStateChanged修复了该问题。

let onLogin:Function = () => {};

export function setOnLogin(func: Function){
    onLogin = func;
}

export function login() {
    signInWithPopup(auth, provider).then(async (result) => {
        const user = result.user;

        await setDoc(doc(db, "users", user.uid), {
            name: user.displayName,
            email: user.email,
        }, {merge: true}); 

        onLogin();

    }).catch(error => {
        //..
    })
}

我一直使用它的注销功能,因为没有这样的问题时,用户注销。

useEffect(() => {
      setOnLogin(() => {
        setLoggedIn(true);
        updateTasks();
      })
      
      onAuthStateChanged(auth, (user) => {
        if(!user){
          setTasks([]);
        }
      })

  }, []);

相关问题