next-firebase-auth用PhoneAuthProvider因reCAPTCHA报app.auth错
报错核心原因
你遇到的app.auth is not a function是典型的Firebase版本兼容问题:
- 你使用的Firebase v9.8.4默认是模块化API,不存在
app.auth()这个旧版命名空间方法 - 但当前稳定版的
firebaseui/react-firebaseui并没有适配v9模块化API,内部仍然调用v8版本的app.auth()方法获取auth实例 - 你额外手动实例化的模块化版
RecaptchaVerifier和firebaseui内置的reCAPTCHA逻辑冲突,同时你在组件渲染阶段直接调用setPersistence、修改auth配置的写法会在SSR阶段触发异常,进一步放大问题。
修复步骤
- 引入Firebase官方提供的auth compat兼容包,不需要升级/降级任何依赖版本
- 删除你手动写的
RecaptchaVerifier实例化代码,firebaseui会自动处理reCAPTCHA的渲染、验证全流程,手动挂载反而会造成逻辑冲突 - 所有浏览器端相关的auth配置(持久化设置、测试模式开关)全部移到
useEffect里执行,避免Next.js服务端渲染阶段调用浏览器API报错 - 传给
StyledFirebaseAuth组件的firebaseAuth属性,必须是compat层返回的auth实例,不能直接传模块化API的getAuth()返回值 - 不需要手动写id为
recaptcha的DOM容器,firebaseui会自动注入reCAPTCHA需要的节点
修正后的完整代码
// /* globals window */ import React, { useEffect, useState } from 'react' import StyledFirebaseAuth from 'react-firebaseui/StyledFirebaseAuth' import { getApp } from 'firebase/app'; // 引入官方兼容层,适配firebaseui的旧版API调用 import 'firebase/compat/auth'; import { getAuth, EmailAuthProvider, setPersistence, browserSessionPersistence, PhoneAuthProvider } from "firebase/auth"; const firebaseAuthConfig = { signInFlow: 'popup', signInOptions: [ { provider: EmailAuthProvider.PROVIDER_ID, requireDisplayName: true, }, { provider: PhoneAuthProvider.PROVIDER_ID, defaultCountry: 'BR', recaptchaParameters: { type: 'image', size: 'invisible', badge: 'bottomright' }, }, ], credentialHelper: 'none', callbacks: { signInSuccessWithAuthResult: () => false, }, }; const FirebaseAuth = () => { const [renderAuth, setRenderAuth] = useState(false); const [compatAuth, setCompatAuth] = useState(null); useEffect(() => { if (typeof window === 'undefined') return; // 初始化compat层auth实例给firebaseui使用 const app = getApp(); const authInstance = app.auth(); setCompatAuth(authInstance); // 持久化配置和测试配置放到副作用里执行,避免SSR报错 const modularAuth = getAuth(app); setPersistence(modularAuth, browserSessionPersistence); // 仅本地开发测试时打开下面这行,生产环境务必删除 // modularAuth.settings.appVerificationDisabledForTesting = true; setRenderAuth(true); }, []); return ( <div> {renderAuth && compatAuth ? ( <StyledFirebaseAuth uiConfig={firebaseAuthConfig} firebaseAuth={compatAuth} /> ) : null} </div> ) } export default FirebaseAuth
注意事项
- 手机号配置里单一只允许巴西用户直接用
defaultCountry: 'BR'即可,不需要额外加白名单配置 auth.settings.appVerificationDisabledForTesting = true仅能在本地开发测试时使用,生产环境必须注释掉,否则会绕过手机号验证逻辑造成安全风险,且线上环境该配置不会生效- 部署上线前记得去Firebase控制台开启手机号认证provider,同时把你的线上域名加入Firebase Auth的授权域名列表,否则reCAPTCHA会报域名不合法错误
内容的提问来源于stack exchange,提问作者Danide Rodrigues
相关产品推荐
相关产品推荐

