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

Firebase Hosting合并部署失败及Netlify路由跳转异常求助

TodoMate部署问题排查(React + Firebase + Vite)

问题概述

  • 代码推送到GitHub后,「Deploy to Firebase Hosting on merge - main」工作流执行失败
  • Netlify部署后,用户登录出现路由在/login和/overview之间频繁切换的循环问题

相关代码

Layout.tsx

const Layout = () => {
  const user = auth.currentUser;
  const location = useLocation();

  if (location.pathname === "/")
    return user ? <Navigate to="/overview" /> : <Navigate to="/login" />;

  return (
    <Stack direction="row">
      <Box sx={{ display: { xs: "none", sm: "block", height: "100vh" } }}>
        <Sidebar />
      </Box>
      <Home />
    </Stack>
  );
};

PrivateRoutes.tsx

const PrivateRoutes = () => {
  const [user, setUser] = useState<User | null>(null);
  const navigate = useNavigate();

  useEffect(() => {
    const unsubscribe = () => {
      auth.onAuthStateChanged((user) => {
        if (user) {
          setUser(user);
          navigate("/overview");
        } else {
          navigate("/login");
        }
      });
    };

    return () => unsubscribe();
  }, []);

  return user ? <Layout /> : <Navigate to="/login" />;
};

Firebase GitHub Action配置

firebase-hosting-merge.yml

# firebase-hosting-merge.yml
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools

name: Deploy to Firebase Hosting on merge
'on':
  push:
    branches:
      - main
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_TODOMATE_F955D }}'
          channelId: live
          projectId: todomate-f955d

firebase-hosting-pull-request.yml

# firebase-hosting-pull-request.yml
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools

name: Deploy to Firebase Hosting on PR
'on': pull_request
jobs:
  build_and_preview:
    if: '${{ github.event.pull_request.head.repo.full_name == github.repository }}'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: npm ci && npm run build
      - uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_TODOMATE_F955D }}'
          projectId: todomate-f955d

问题分析与解决方案

1. Netlify路由循环问题

问题根源:

  • PrivateRoutes中onAuthStateChanged回调每次检测到用户存在,就强制执行navigate("/overview"),即使当前路由已经是/overview,这会触发组件重新渲染,导致循环调用
  • auth.currentUser是同步值,页面初始化时Firebase Auth尚未完成会话恢复,可能出现误判

修复方案:
修改PrivateRoutes.tsx,移除强制跳转逻辑,添加加载状态避免误判:

const PrivateRoutes = () => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const navigate = useNavigate();
  const location = useLocation();

  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((user) => {
      setUser(user);
      setLoading(false);
      // 仅在未登录且当前不是登录页时跳转
      if (!user && location.pathname !== "/login") {
        navigate("/login");
      }
    });

    return unsubscribe;
  }, [location, navigate]);

  if (loading) {
    return <div>Loading...</div>;
  }

  if (!user) {
    return <Navigate to="/login" />;
  }

  return <Layout />;
};

修改Layout.tsx,仅在根路径且用户已登录时执行重定向:

const Layout = () => {
  const user = auth.currentUser;
  const location = useLocation();

  if (location.pathname === "/" && user) {
    return <Navigate to="/overview" replace />;
  }

  return (
    <Stack direction="row">
      <Box sx={{ display: { xs: "none", sm: "block", height: "100vh" } }}>
        <Sidebar />
      </Box>
      <Home />
    </Stack>
  );
};

2. Firebase GitHub Action部署失败问题

问题根源:
对比PR工作流,merge工作流缺少依赖安装和项目构建步骤,Firebase Hosting需要部署编译后的dist目录,直接部署源码会导致失败。

修复方案:
在firebase-hosting-merge.yml中添加依赖安装和构建命令:

name: Deploy to Firebase Hosting on merge
'on':
  push:
    branches:
      - main
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: npm ci && npm run build # 新增构建步骤
      - uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_TODOMATE_F955D }}'
          channelId: live
          projectId: todomate-f955d

额外检查项:

  • 确认GitHub Secrets中的FIREBASE_SERVICE_ACCOUNT_TODOMATE_F955D配置正确
  • 本地执行npm run build能正常生成dist目录,无编译报错

onAuthStateChanged使用建议

推荐使用onAuthStateChanged监听用户状态,而非依赖同步的auth.currentUser:

  • auth.currentUser在页面初始化时可能为null,无法准确反映用户真实状态
  • onAuthStateChanged会在Firebase Auth完成会话恢复后触发回调,状态判断更可靠
  • 结合加载状态可以避免用户看到不必要的重定向或错误页面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:50:07