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

Firebase注册代码修复:Authentication创建用户后无法写入Firestore

修复Firebase注册后用户信息无法存入Firestore的问题

原代码核心问题

  • 拼写错误:snapshot.exist应为snapshot.exists,且通过get()获取整个users集合快照判断存在性的逻辑错误,需检查当前用户ID对应的文档而非整个集合
  • 重复的密码长度校验逻辑,冗余无意义
  • 创建Auth用户后重复判断集合快照存在性,逻辑矛盾导致Firestore写入代码无法执行
  • isValid初始值为布尔值,后续赋值为对象,类型不统一引发状态异常

修复后的完整代码

import { useState } from 'react';
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

export default function Register(props) {
  const [firstname, setFirstname] = useState('');
  const [lastname, setLastname] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [phonenumber, setPhonenumber] = useState('');
  // 统一isValid为对象类型,初始状态隐藏提示
  const [isValid, setIsValid] = useState({ bool: false, boolSnack: false, message: "" });

  const onSignup = async () => {
    // 表单校验
    if (!firstname || !lastname || !email || !password) {
      setIsValid({ bool: true, boolSnack: true, message: "请填写所有必填项" });
      return;
    }
    if (password.length < 6) {
      setIsValid({ bool: true, boolSnack: true, message: "密码长度至少为6位" });
      return;
    }

    try {
      // 1. 创建Auth用户,直接获取用户凭证避免依赖currentUser的异步延迟
      const userCredential = await firebase.auth().createUserWithEmailAndPassword(email, password);
      const user = userCredential.user;

      // 2. 定位到当前用户的Firestore文档
      const userDocRef = firebase.firestore().collection("users").doc(user.uid);
      const docSnapshot = await userDocRef.get();

      if (!docSnapshot.exists) {
        // 3. 写入用户信息到Firestore
        await userDocRef.set({
          email: user.email,
          emailVerified: user.emailVerified,
          firstname,
          lastname,
          phonenumber,
          disabled: user.disabled
        });
        // 注册成功后可添加跳转逻辑,比如props.navigation.navigate('Home')
      } else {
        setIsValid({ bool: true, boolSnack: true, message: "该用户信息已存在" });
      }
    } catch (error) {
      // 捕获具体错误信息,方便调试
      setIsValid({ bool: true, boolSnack: true, message: error.message || "注册失败,请重试" });
    }
  };

  // 基础表单渲染示例
  return (
    <div>
      <input type="text" value={firstname} onChange={(e) => setFirstname(e.target.value)} placeholder="名" />
      <input type="text" value={lastname} onChange={(e) => setLastname(e.target.value)} placeholder="姓" />
      <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="邮箱" />
      <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="密码" />
      <input type="tel" value={phonenumber} onChange={(e) => setPhonenumber(e.target.value)} placeholder="手机号" />
      <button onClick={onSignup}>注册</button>
      {isValid.boolSnack && <div className="error-tip">{isValid.message}</div>}
    </div>
  );
}

关键优化点

  1. 修正状态变量命名为驼峰规范,提升代码可读性
  2. 统一isValid状态类型为对象,避免类型冲突
  3. 使用async/await替代嵌套then/catch,逻辑更清晰
  4. 通过userCredential直接获取用户ID,避免currentUser的异步延迟问题
  5. 正确检查单个用户文档的存在性,而非整个集合
  6. 捕获具体错误信息,便于定位问题
  7. 补充基础表单渲染逻辑,确保代码可直接运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:15:41