You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase数据渲染报错:无法读取未定义属性'indexOf'

问题修复:Firebase读取用户待办事项时的TypeError错误

错误根源

你碰到的Cannot read properties of undefined (reading 'indexOf')错误,核心原因是组件初始化阶段user.uid为undefined,传入Firebase的doc()函数后引发报错:

  • 监听认证状态的onAuthStateChanged是异步操作,组件挂载时第二个useEffect会优先执行,此时user还是初始的空对象{},user.uid不存在;
  • 即便把user加入第二个useEffect的依赖数组,第一次执行时user仍为空对象,还是会触发一次错误,直到user更新后才会正常运行。

解决方案

在调用Firebase接口前先校验user有效性,同时处理文档不存在的边界情况:

// useStates
const [newTodos, setNewTodos] = useState([]);
const [user, setUser] = useState(null); // 初始值设为null更贴合未登录状态

useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
        setUser(currentUser);
    });

    // 清理auth订阅,避免内存泄漏
    return unsubscribe;
}, [])

useEffect(() => {
    const getTodos = async () => {
        // 先校验用户是否有效,无效则直接返回
        if (!user?.uid) return;
        
        try {
            const userDoc = doc(db, "users", user.uid);
            const docSnap = await getDoc(userDoc);
            
            // 处理用户文档不存在的情况
            if (docSnap.exists()) {
                // 确保todos是数组,避免数据异常
                const todoList = docSnap.data().todos || [];
                setNewTodos(todoList);
            } else {
                // 文档不存在时初始化空数组
                setNewTodos([]);
            }
        } catch (err) {
            console.error("获取待办事项失败:", err);
        }
    }
    getTodos();
}, [user]) // 依赖user,用户切换时自动重新获取数据

关键修改说明

  1. 调整user初始值:从空对象改为null,更清晰表示“未登录”状态,判断逻辑更直观;
  2. 添加用户有效性校验:if (!user?.uid) return;确保只有当用户存在且拥有有效uid时,才执行Firebase操作;
  3. 处理文档不存在场景:用docSnap.exists()判断,避免读取不存在的文档数据引发报错;
  4. 增加错误捕获:用try/catch包裹异步操作,便于排查后续可能出现的异常;
  5. 清理auth订阅:onAuthStateChanged返回的unsubscribe函数在组件卸载时执行,防止内存泄漏。

关于onLoad事件的补充说明

div元素不支持onLoad事件,只有图片、脚本等资源类元素会触发该事件,所以之前通过onLoad调用getTodos的尝试无效,数据获取逻辑仍需依赖useEffect实现。

内容的提问来源于stack exchange,提问作者Luka Miljković

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:09:23