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

Next.js+Firebase部署报错:Cannot access 'auth' before initialization

问题分析

这个报错的核心原因是Next.js构建预渲染(SSG/SSR)时,在服务器端执行了依赖浏览器环境的Firebase Auth初始化逻辑,同时可能存在重复初始化或环境变量未正确注入的问题。本地开发正常是因为开发模式下更多依赖客户端渲染,而部署构建时会强制预渲染页面,触发服务器端代码执行。

解决方案

1. 修改Firebase配置文件,适配服务器端环境

将Firebase的初始化改为单例模式,并仅在客户端环境初始化Auth和Firestore(客户端SDK不支持服务器端运行):

import { initializeApp, getApps, getApp } from "firebase/app";
import {
    signInWithPopup,
    GoogleAuthProvider,
    FacebookAuthProvider,
    signInWithEmailAndPassword,
    getAuth,
    signOut,
} from "firebase/auth";
import {
    getFirestore,
    getDocs,
    collection,
    deleteDoc,
    doc,
    setDoc,
} from "firebase/firestore";
import { toast } from "react-toastify";

const firebaseConfig = {
    apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
    authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
    projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
    storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
    appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
    measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
};

// 单例模式:避免重复初始化Firebase App
const firebaseApp = getApps().length > 0 ? getApp() : initializeApp(firebaseConfig);

let auth;
let db;

// 仅在客户端环境初始化Auth和Firestore
if (typeof window !== 'undefined') {
    auth = getAuth(firebaseApp);
    db = getFirestore(firebaseApp);
}

const googleProvider = new GoogleAuthProvider();
const facebookProvider = new FacebookAuthProvider();

// ...你的其他方法,注意如果方法用到auth/db,要确保仅在客户端调用

export { auth, db, googleProvider, facebookProvider };

2. 调整_app.js中的Auth逻辑,避免服务器端执行useAuthState

在Pages Router中,_app.js会同时在服务器端和客户端执行,需要确保useAuthState仅在客户端运行。可以通过useEffect延迟获取用户:

import React, { useState, useEffect } from "react";
import { useLocalStorage } from "../components/useLocalStorage";
import { auth } from "../firebase";
import Layout from "../components/Layout";
import ExerciseContextProvider from "../context/state";

function MyApp({ Component, pageProps }) {
    const [myWorkout, setMyWorkout] = useLocalStorage("exercise", []);
    const [user, setUser] = useState(null);
    const [loading, setLoading] = useState(false);

    // 仅在客户端初始化用户状态
    useEffect(() => {
        if (!auth) return;
        const unsubscribe = auth.onAuthStateChanged((currentUser) => {
            setUser(currentUser);
        });
        return unsubscribe;
    }, [auth]);

    return (
        <>
            <ExerciseContextProvider>
                <Layout user={user}>
                    <Component
                        {...pageProps}
                        user={user}
                        loading={loading}
                        setLoading={setLoading}
                        myWorkout={myWorkout}
                        setMyWorkout={setMyWorkout}
                    />
                </Layout>
            </ExerciseContextProvider>
        </>
    );
}

export default MyApp;

3. 确认部署时的环境变量配置

部署到Firebase Hosting时,必须确保所有NEXT_PUBLIC_前缀的环境变量已正确配置:

  • 在Firebase控制台的「项目设置」→「环境变量」中添加对应变量;
  • 或在项目根目录创建.env.production文件,写入变量并确保该文件被包含在部署包中。

4. 禁用特定页面的预渲染(可选)

如果某些页面不需要预渲染,可以在页面文件中添加:

export const getStaticProps = async () => {
    return {
        props: {},
        revalidate: false, // 禁用静态生成
    };
};

此方案会影响页面性能,仅作为临时应急方案使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:19:55