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

React JS使用模块化Firebase v9操作Firestore报indexOf未定义错误如何解决

问题根因

你触发报错的核心原因有两个:

  • React的setState是异步更新,调用setUserData(user)之后,同步代码里访问userData拿不到刚生成的用户对象,此时userData还是初始的空字符串,userData.uid为undefined,传给Firestore路径参数时,Firestore内部调用indexOf处理路径字符串时拿到非有效值,直接抛出异常。
  • Firestore API使用不符合需求:你要使用用户uid作为自定义文档ID存储数据,不能用addDoc(addDoc是给集合自动生成随机文档ID的API),需要搭配doc和setDoc实现指定ID文档的写入。

修复后的代码

import React, { useState, useCallback } from 'react'
import { auth, db } from "../firebase"
import { createUserWithEmailAndPassword } from "firebase/auth";
import { doc, setDoc } from "firebase/firestore"; 

function Login() {
    const [email, setEmail] = useState('')
    const [pass, setPass] = useState('')
    const [error, setError] = useState('')

    const ProcessData = e => {
        e.preventDefault()
        registro()
    }

    const registro = useCallback(async() => {
        try {
            // 直接await获取认证返回的用户凭证,不需要通过状态中转
            const userCredential = await createUserWithEmailAndPassword(auth, email, pass)
            const user = userCredential.user;
            
            // 用当前拿到的用户uid作为文档ID,写入数据
            await setDoc(doc(db, 'users', user.uid), {
                email: user.email,
                uid: user.uid
            })
            
            setEmail('')
            setPass('')
            setError('')

        } catch (error) {
            const errorMessage = error.message;
            setError(errorMessage)
            console.log(error)
        }
    // 依赖仅保留email和pass即可,移除不必要的依赖避免重复触发逻辑
    }, [email, pass])

    return (
        <div>
            <h3>Registro</h3>
            <form onSubmit={ProcessData}>
                <label>Email Adress</label>
                <input
                type="email"
                placeholder="Email Address"
                onChange={e => setEmail(e.target.value)}
                value={email}
                />
                <label>Password</label>
                <input
                type="password"
                placeholder="Password"
                onChange={e => setPass(e.target.value)}
                value={pass}
                />
                <button type="submit">Registrarse</button>
                {error && <p style={{color: 'red'}}>{error}</p>}
            </form>
        </div>
    )
}

export default Login

额外优化说明

  • 移除了不必要的userData状态,避免异步状态更新带来的逻辑异常
  • 清理了未使用的addDoc、collection导入,减少冗余代码
  • 新增了错误信息的前端展示,方便用户感知操作异常

内容的提问来源于stack exchange,提问作者iandev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:24:00