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

用户创建成功后useNavigate页面不跳转问题(Firebase用户正常创建)

问题排查与修复方案

核心问题:上传任务的完成回调逻辑错误

你当前使用uploadTask.on()的第二个参数作为完成回调,但这个参数实际是状态变化回调,并非上传完成时触发的回调。这直接导致后续的navigate代码根本没执行,是页面不跳转的核心原因。

修复后的代码

import { Link, useNavigate } from "react-router-dom";
import { useContext, useState } from "react";
import { createUserWithEmailAndPassword, updateProfile, auth } from "../firebase";
import { ref, uploadBytesResumable, getDownloadURL, storage } from "../firebase/storage";
import { setDoc, doc, db } from "../firebase/firestore";
import { AuthContext } from "../context/AuthContext";

const Signup = ({ socket }) => {
    const currentUser = useContext(AuthContext);
    const navigate = useNavigate();
    const [err, setErr] = useState(false);

    const handleSubmit = async (e) => {
        e.preventDefault();

        const displayName = e.target[0].value;
        const email = e.target[1].value;
        const password = e.target[2].value;
        const profilePic = e.target[3].files[0];

        try {
            const res = await createUserWithEmailAndPassword(auth, email, password);

            const storageRef = ref(storage, displayName);
            const uploadTask = uploadBytesResumable(storageRef, profilePic);

            // 正确监听上传事件:进度回调、错误回调、完成回调
            uploadTask.on('state_changed',
                (snapshot) => {
                    // 可选:在这里处理上传进度,比如显示进度条
                },
                (error) => {
                    setErr(true);
                    console.error("头像上传失败:", error);
                },
                async () => {
                    try {
                        const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
                        
                        await updateProfile(res.user, {
                            displayName,
                            photoURL: downloadURL,
                        });

                        await setDoc(doc(db, "users", res.user.uid), {
                            uid: res.user.uid,
                            displayName,
                            email,
                            photoURL: downloadURL,
                        });

                        // 用刚创建的用户对象,避免AuthContext未同步的问题
                        socket.emit("newUser", {
                            currentUser: res.user,
                            socketID: socket.id,
                        });

                        navigate("/join_room");
                    } catch (innerErr) {
                        setErr(true);
                        console.error("用户信息同步失败:", innerErr);
                    }
                }
            );
        } catch (outerErr) {
            setErr(true);
            console.error("用户创建失败:", outerErr);
        }
    };

    // 组件渲染逻辑...
};

export default Signup;

额外优化点

  • 用户对象同步:刚创建用户后,AuthContext中的currentUser可能未及时更新,所以socket.emit时直接用res.user(创建用户返回的实时对象),避免传空值或旧数据。
  • 错误日志完善:给每个异步操作添加错误打印,方便快速定位问题节点。
  • 回调顺序修正:严格遵循uploadTask.on()的参数顺序:进度回调→错误回调→完成回调,确保完成逻辑在上传成功后触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:17:29