ReactJS SPA中Firebase/FirebaseUI认证报错u[v] is not a function如何解决?
使用Firebase任意登录提供商登录时出现异常:浏览器中Firebase需等待10秒后才能恢复并完成认证,移动端耗时更长。
报错信息如下:
api.js?onload=__iframefcb695643:29 Uncaught TypeError: u[v] is not a function at Q.<computed> [as loaded_0] (api.js?onload=__iframefcb695643:29:145) at cb=gapi.loaded_0?le=scs:1:6
该错误引发认证逻辑异常:尽管OAuth调用(如Google OAuth的https://identitytoolkit.googleapis.com/v1/accounts:lookup)已成功,但auth.onAuthStateChanged始终不返回用户信息。
已尝试更换Firebase版本、调整导入方式,问题仍未解决。当前环境为ReactJS单页应用,使用兼容模式的Firebase与FirebaseUI,版本信息:"firebase": "^10.7.1","firebaseui": "^6.1.0"。
Firebase初始化代码:
import firebase from 'firebase/compat/app'; import 'firebase/compat/auth'; import * as firebaseui from 'firebaseui'; import { User, onAuthStateChanged, EmailAuthProvider, GoogleAuthProvider, OAuthProvider } from 'firebase/auth'; const firebaseConfig = { ... }; const app = firebase.initializeApp(firebaseConfig); const auth = firebase.auth(); auth.languageCode = 'nl'; export { app, auth };
React页面(home.tsx)中加载登录UI的函数:
const setupFirebaseAuthUI = () => { const ui = firebaseui.auth.AuthUI.getInstance() || new firebaseui.auth.AuthUI(auth); const providerApple = new OAuthProvider('apple.com'); const uiConfig = { signInOptions: [EmailAuthProvider.PROVIDER_ID, GoogleAuthProvider.PROVIDER_ID, providerApple.providerId], callbacks: { signInSuccessWithAuthResult: authResult => { navigate('/'); return false; }, }, privacyPolicyUrl: 'https://example.nl/privacy', tosUrl: 'https://example.nl/voorwaarden', }; ui.start('#firebaseui-auth-container', uiConfig); };
统一Auth导入模式:当前代码混合了compat兼容模式和模块化导入,会导致Auth实例冲突。将所有Auth相关的导入统一改为compat模式:
// 替换原模块化导入语句 import { User, onAuthStateChanged, EmailAuthProvider, GoogleAuthProvider, OAuthProvider } from 'firebase/compat/auth';确保DOM就绪后初始化FirebaseUI:在React中,需确认
#firebaseui-auth-container元素已渲染完成,再调用初始化函数。可通过useEffect钩子实现:useEffect(() => { const container = document.getElementById('firebaseui-auth-container'); if (container) { setupFirebaseAuthUI(); } }, []);优化AuthUI实例管理:若页面存在多次渲染场景,可先销毁旧的AuthUI实例再创建新实例,避免残留状态导致的冲突:
const existingUi = firebaseui.auth.AuthUI.getInstance(); if (existingUi) { existingUi.delete(); } const newUi = new firebaseui.auth.AuthUI(auth); newUi.start('#firebaseui-auth-container', uiConfig);验证版本兼容性:虽然当前版本理论兼容,但可尝试调整FirebaseUI版本,比如降级到
firebaseui@6.0.2或升级至最新兼容版,排除版本匹配问题。排查GAPI重复加载:报错来自Google的GAPI脚本,FirebaseUI会自动加载GAPI,需确保页面中没有手动引入额外的GAPI脚本,避免重复加载引发冲突。
内容的提问来源于stack exchange,提问作者Peter F

