Vue集成Firebase查询用户宠物时出现uid读取空值报错
问题排查:Firebase获取当前用户宠物列表报错Cannot read properties of null (reading 'uid')
报错信息
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'uid')
问题根因
这个错误的触发逻辑非常直接:你执行user.value.uid读取uid时,user.value的值是null,根本没有拿到有效的登录用户对象。
本质原因是Firebase Auth的用户登录状态是异步初始化的:你在setup阶段刚调用getUser()拿到响应式user对象时,SDK还没完成鉴权状态校验,此时user的默认值就是null,直接访问它的uid属性必然抛错。
除此之外你现有代码还有3个会导致运行异常的问题:
- 没有在组件卸载时取消Firestore的实时快照监听,会造成内存泄漏
- 遍历查询结果写入数组的写法有误:
doc.data()返回的是单条宠物文档的对象,直接用展开运算符push会把对象的属性拆成零散项存入数组,后续调用join会得到不符合预期的结果 - return语句里返回了从未定义过的
error变量,运行时会触发额外的未定义错误
修复后的实现代码
需要等用户状态加载完成、确认存在有效登录用户后再初始化查询,同时做好监听解绑、数据格式修正:
<script> // @ 是 /src 目录的路径别名 import getUser from "@/composables/getUser" import { auth, db } from "@/firebase/config"; import {signOut} from "firebase/auth"; import { collection, onSnapshot, query, where } from '@firebase/firestore'; import { ref, watch, onUnmounted } from 'vue' import { useRouter } from 'vue-router' export default { name: 'HomeView', setup(){ const {user} = getUser() const router = useRouter() const petList = ref([]) let unsubscribe = null // 监听用户状态变化,用户有效时才发起查询 watch(user, (currentUser) => { // 先取消之前可能存在的旧监听,避免重复绑定 if (unsubscribe) { unsubscribe() unsubscribe = null } // 用户未登录时直接清空列表,不发起无效查询 if (!currentUser) { petList.value = [] return } // 确认用户存在后再构建查询条件 const q = query(collection(db,"pets"), where("UserID", "==", currentUser.uid)) unsubscribe = onSnapshot(q, (querySnapshot)=>{ const tempPets = [] querySnapshot.forEach((doc)=> { // 合并文档id和文档数据存入,方便后续做编辑、删除操作 tempPets.push({ id: doc.id, ...doc.data() }) }) petList.value = tempPets console.log("Current pets :", petList.value) }) }, { immediate: true }) // 组件卸载时取消监听,防止内存泄漏 onUnmounted(() => { if (unsubscribe) unsubscribe() }) return { petList, signOut } } } </script>
验证要点
- 修复后会自动响应用户登录状态变化:用户登录成功后自动拉取对应宠物列表,用户退出登录后自动清空列表
- 如果你的
getUser组合式函数没有加载状态字段,建议补充isLoading响应式变量,页面加载阶段可以展示loading态,避免空状态闪烁 - 确保Firestore安全规则配置正确,允许登录用户读取自身UserID关联的pets文档,否则查询会因权限校验失败报错
内容的提问来源于stack exchange,提问作者suffian
相关产品推荐
相关产品推荐

