在Next JS中如何正确放置Firebase认证预制UI相关代码?
你目前的写法存在两个核心问题:
- React组件中不能直接把业务逻辑写在
<script>标签内,逻辑需要放在组件的生命周期钩子中执行 - NextJS默认有服务端渲染逻辑,FirebaseUI依赖浏览器的window对象,服务端执行时不存在window会报错
步骤1:确保依赖已安装
首先安装所需依赖:
npm install firebase firebaseui
步骤2:改造LoggedIn组件
使用useEffect钩子,确保逻辑仅在客户端渲染完成后执行,同时处理实例的重复初始化和卸载清理:
import Box from '@mui/material/Box' import { GoogleAuthProvider, getAuth } from 'firebase/auth' import app from '../firebase' // 确保该文件已正确初始化Firebase项目 import * as firebaseui from 'firebaseui' import 'firebaseui/dist/firebaseui.css' // 导入FirebaseUI默认样式 import { useEffect, useRef } from 'react' export default function LoggedIn() { // 用ref存储FirebaseUI实例,避免重复初始化 const uiRef = useRef(null) const auth = getAuth(app) useEffect(() => { // 仅在客户端环境执行,避免SSR阶段window未定义报错 if (typeof window === 'undefined') return const uiConfig = { signInSuccessUrl: '/sandbox/login/signup', signInOptions: [ GoogleAuthProvider.PROVIDER_ID, // 其他登录方式可以在这里添加,比如Facebook、Github、邮箱登录等 ], tosUrl: '/', privacyPolicyUrl: '/' } // 避免重复创建UI实例 if (!uiRef.current) { uiRef.current = new firebaseui.auth.AuthUI(auth) } // 渲染登录组件到指定容器 uiRef.current.start('#firebaseui-auth-container', uiConfig) // 组件卸载时清理实例,避免内存泄漏 return () => { if (uiRef.current) { uiRef.current.delete() uiRef.current = null } } }, [auth]) return ( <Box> <h1>欢迎来到我的应用</h1> <Box id="firebaseui-auth-container"></Box> </Box> ) }
额外优化(可选)
如果还是出现window未定义的报错,可以在引入LoggedIn组件的页面使用NextJS动态导入,关闭该组件的服务端渲染:
import dynamic from 'next/dynamic' // 注意替换为你自己的组件路径 const LoggedIn = dynamic(() => import('../components/LoggedIn'), { ssr: false })
注意事项
- 确保你项目中的
firebase.js配置文件已正确填写Firebase控制台获取的初始化参数,不存在重复初始化的问题 - 如果不需要默认的页面跳转逻辑,可以在
uiConfig中添加signInSuccessWithAuthResult回调,自定义登录成功后的处理逻辑
内容的提问来源于stack exchange,提问作者engineer-x
相关产品推荐
相关产品推荐

