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

Next.js集成Google Firebase认证时应用崩溃问题求助

解决Next.js中Firebase Google认证崩溃问题

问题根源分析

报错dependent-sdk-initialized-before-auth说明其他Firebase SDK在Auth完成初始化前就尝试调用Auth功能,同时代码存在几处直接触发崩溃的问题:

  • logoutFirebase函数中signOut未导入,会直接抛出未定义错误
  • 直接通过auth.currentUser判断登录状态,在Next.js的服务端渲染/静态生成环境下不可靠,且无法实时监听状态变化
  • 未处理Firebase在Next.js中的重复初始化问题(热重载或多页面导入可能触发)

分步修复方案

1. 修正firebase-config.js配置

import { initializeApp, getApps, getApp } from 'firebase/app';
import { 
  initializeAuth, 
  browserLocalPersistence, 
  browserPopupRedirectResolver, 
  indexedDBLocalPersistence, 
  signInWithRedirect, 
  GoogleAuthProvider,
  signOut, 
  onAuthStateChanged 
} from "firebase/auth";

const firebaseCredentials = {
  apiKey: process.env.FIREBASE_API_KEY,
  authDomain: process.env.AUTH_DOMAIN,
  projectId: process.env.PROJECT_ID,
  storageBucket: process.env.STORAGE_BUCKET,
  messagingSenderId: process.env.MESSAGING_SENDER_ID,
  appId: process.env.APP_ID
};

// 单例模式避免重复初始化
let app;
let auth;

if (!getApps().length) {
  app = initializeApp(firebaseCredentials);
  
  // 优先初始化Auth,确保其他Firebase服务在Auth之后初始化
  auth = initializeAuth(app, {
    persistence: [indexedDBLocalPersistence, browserLocalPersistence],
  });
} else {
  app = getApp();
  auth = getAuth(app);
}

// 替换同步获取用户的方法,改为提供状态监听函数
export const listenToAuthState = (callback) => {
  return onAuthStateChanged(auth, callback);
};

export const loginFirebase = () => {
  signInWithRedirect(auth, new GoogleAuthProvider(), browserPopupRedirectResolver);
};

export const logoutFirebase = () => {
  signOut(auth);
};

2. 重构Auth组件,正确监听登录状态

'use client' // Next.js 13+版本需添加,确保组件在客户端运行
import { useRouter } from 'next/router';
import { useState, useEffect } from 'react';
import { IconButton, Menu, MenuItem, Button, Box } from '@mui/material';
import { AccountCircle, Logout, ManageAccounts, RateReview, Google } from '@mui/icons-material';
import { listenToAuthState, loginFirebase, logoutFirebase } from '../firebase-config';

export const Auth = () => {
  const router = useRouter();
  const [anchorEl, setAnchorEl] = useState(null);
  const [user, setUser] = useState(null); 

  useEffect(() => {
    // 监听Auth状态变化,实时更新用户信息
    const unsubscribe = listenToAuthState((currentUser) => {
      setUser(currentUser);
    });

    // 组件卸载时取消监听
    return () => unsubscribe();
  }, []);

  const handleMenu = (event) => setAnchorEl(event.currentTarget);
  const handleClose = () => setAnchorEl(null);
  const redirectFromMenu = (url) => {
    handleClose();
    router.push(url);
  };

  return (
    <Box sx={{ marginLeft: 'auto' }}>
      {user ? (
        <>
          <IconButton
            size="large"
            aria-label="account of current user"
            aria-controls="menu-appbar"
            aria-haspopup="true"
            onClick={handleMenu}
            color="inherit"
          >
            <AccountCircle />
          </IconButton>
          <Menu
            id="menu-appbar"
            anchorEl={anchorEl}
            anchorOrigin={{
              vertical: 'top',
              horizontal: 'right',
            }}
            keepMounted
            transformOrigin={{
              vertical: 'top',
              horizontal: 'right',
            }}
            open={Boolean(anchorEl)}
            onClose={handleClose}
          >
            <MenuItem onClick={() => redirectFromMenu('/account')}><ManageAccounts />&nbsp;My Account</MenuItem>
            <MenuItem onClick={() => redirectFromMenu('/reviews/write')}><RateReview />&nbsp;Write Review</MenuItem>
            <MenuItem onClick={logoutFirebase}><Logout />&nbsp;Logout</MenuItem>
          </Menu>
        </>
      ) : (
        <Button size='small' onClick={loginFirebase} startIcon={<Google />} variant='contained' color='secondary'>
          Login with Google
        </Button>
      )}
    </Box>
  );
};

3. 额外注意事项

  • 确保所有其他Firebase服务(如Firestore、Storage)的初始化代码都在Auth初始化之后执行
  • 检查.env.local文件,确认所有Firebase环境变量都已正确配置,且变量名与代码中的一致
  • 若使用Next.js 13+ App Router,需确保Auth组件为客户端组件(添加'use client'指令)

内容的提问来源于stack exchange,提问作者J. Whitehead

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:15:36