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

Next.js+Firebase登录系统:如何等待Firestore数据再执行页面跳转?

解决方案与问题分析

核心问题分析

  1. 异步执行顺序错误:signInWithEmailAndPassword是异步操作,你直接在其后调用getData()和pushToPage()时,登录流程还未完成,databaseRef仍是初始空字符串,导致getDoc()接收无效参数触发报错;同时getData()是异步函数,返回的是Promise对象,而非实际角色值,pushToPage()拿到的不是有效字符串,跳转逻辑完全失效。
  2. 不必要的状态监听:登录成功后,signInWithEmailAndPassword的返回结果已包含当前用户对象,无需再通过onAuthStateChanged监听,监听更适合处理页面刷新、自动登录等场景,这里反而会延迟databaseRef的赋值。
  3. 全局变量风险:依赖全局变量传递databaseRef等数据,容易因异步时序问题导致数据未就绪就被使用。

修复后的代码

登录函数(重构为异步函数)

async function LogIn() {
  try {
    // 等待登录请求完成
    const response = await signInWithEmailAndPassword(auth, email, password);
    sessionStorage.setItem('Token', response.user.accessToken);
    
    // 直接使用登录返回的用户对象,无需额外监听
    const user = response.user;
    if (user) {
      // 生成有效的Firestore文档引用
      const databaseRef = doc(database, 'users', user.uid);
      // 等待角色数据获取完成
      const accountType = await getData(databaseRef);
      // 获取到角色后再执行跳转
      pushToPage(accountType);
    }
  } catch (err) {
    console.log(err.code);
  }
}

获取角色函数(改为参数传递引用)

const getData = async (databaseRef) => {
  try {
    const docSnap = await getDoc(databaseRef);
    if (docSnap.exists()) {
      return docSnap.data().account_type;
    } else {
      console.log('用户文档不存在');
      return 'faculty'; // 文档不存在时返回默认角色,可根据需求调整
    }
  } catch (e) {
    console.log('获取角色失败:', e);
    return 'faculty'; // 出错时返回默认角色,避免跳转异常
  }
};

页面跳转函数(保持不变)

const pushToPage = (accountType) => {
  if (accountType == 'management') {
    router.push('/accounts/management');
  } else if (accountType == 'dean') {
    router.push('/accounts/deans');
  } else {
    router.push('/accounts/faculty');
  }
};

额外检查项

确保你的Firestore实例已正确初始化,示例代码如下:

import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

// 你的Firebase配置
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID"
};

// 初始化Firebase
const app = initializeApp(firebaseConfig);
// 初始化Firestore实例(确保这个database变量被正确传递到你的登录逻辑中)
const database = getFirestore(app);

内容的提问来源于stack exchange,提问作者Joshua Perth Y. Alviso

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:55:18