Vue+Pinia+Firebase:页面加载时获取用户UID失败的技术问询
解决Vue+Pinia+Firebase页面加载时UID未就绪的问题
问题原因
组件的created钩子执行时机过早,此时Firebase用户认证状态还未初始化完成,Pinia的authStore.user还没被赋值,直接访问user.uid自然会得到undefined。
解决方案
方法一:监听Pinia用户状态变化
利用Vue的watch监听authStore.user的变化,当用户对象存在且包含uid时,再执行Firebase集合查询:
import { watch, ref } from 'vue'; import { useAuthStore } from '@/stores/auth'; import { getFirestore, collection, query, getDocs } from 'firebase/firestore'; import { firebaseApp } from '@/firebase/config'; export default { setup() { const db = getFirestore(firebaseApp); const authStore = useAuthStore(); const data = ref({}); // 用响应式ref存储数据 // 监听user状态,用户就绪后执行查询 watch( () => authStore.user, async (user) => { if (user?.uid) { const q = query(collection(db, user.uid)); const querySnapshot = await getDocs(q); querySnapshot.forEach((doc) => { data.value[doc.id] = doc.data(); }); } }, { immediate: true } // 立即检查当前user状态 ); return { data }; } };
方法二:在Pinia中封装用户初始化方法
先在Pinia的认证仓库里添加一个等待用户认证完成的方法,再在组件中等待这个方法完成后执行查询:
1. 改造Pinia的Auth仓库
// stores/auth.js import { defineStore } from 'pinia'; import { getAuth, onAuthStateChanged } from 'firebase/auth'; export const useAuthStore = defineStore('auth', { state: () => ({ user: null }), actions: { async initAuth() { const auth = getAuth(); return new Promise((resolve) => { // 监听Firebase认证状态变化 onAuthStateChanged(auth, (user) => { this.user = user; resolve(user); }); }); } } });
2. 在组件中使用
import { onMounted, ref } from 'vue'; import { useAuthStore } from '@/stores/auth'; import { getFirestore, collection, query, getDocs } from 'firebase/firestore'; import { firebaseApp } from '@/firebase/config'; export default { setup() { const db = getFirestore(firebaseApp); const authStore = useAuthStore(); const data = ref({}); onMounted(async () => { // 等待用户认证初始化完成 const user = await authStore.initAuth(); if (user?.uid) { const q = query(collection(db, user.uid)); const querySnapshot = await getDocs(q); querySnapshot.forEach((doc) => { data.value[doc.id] = doc.data(); }); } }); return { data }; } };
注意事项
- 尽量避免在
created钩子中处理依赖异步状态的逻辑,Vue3推荐使用组合式API(如watch、onMounted)来替代。 - 始终用可选链操作符
?.访问user.uid,避免用户未登录时出现报错。
内容的提问来源于stack exchange,提问作者Peek0
相关产品推荐
相关产品推荐

