React接入Firebase谷歌登录报GoogleAuthProvider不是构造函数错误
报错根因定位
TypeError: firebase.auth.GoogleAuthProvider is not a constructor的核心触发原因是SDK版本和调用语法不匹配:
- 你导出的
firebase变量是initializeApp返回的应用实例对象,并非旧版全量SDK提供的全局命名空间对象 GoogleAuthProvider是auth模块单独导出的构造类,并不会挂载在auth()方法返回的认证服务实例上,因此从实例上取这个类做初始化操作就会抛出构造器不存在的错误
可落地修复方案
根据你现有代码的改动成本,可选择以下任意一种方案实现正常登录逻辑:
方案1:最小改动适配现有调用逻辑
不需要大幅修改signin.js的原有代码逻辑,仅需调整firebase.prod.js的导出结构,把独立的GoogleAuthProvider类显式挂载到导出对象上:
import Firebase from "firebase/app"; import "firebase/firestore"; import "firebase/auth"; import "firebase/storage"; const config = { apiKey: "AIzaSyASOat6CaIWxzwnepoGBHDpltnf9jH1QH0", authDomain: "cv-builder-c0429.firebaseapp.com", databaseURL: "https://cv-builder-c0429.firebaseio.com", storageBucket: "cv-builder-c0429.appspot.com", }; // 初始化应用实例 const firebaseApp = Firebase.initializeApp(config); // 从auth模块显式获取GoogleAuthProvider类 const GoogleAuthProvider = Firebase.auth.GoogleAuthProvider; // 调整导出结构,匹配原有调用语法 export const firebase = { auth: () => { const authInstance = firebaseApp.auth(); // 把GoogleAuthProvider挂载到auth实例上,适配new firebase.auth.GoogleAuthProvider()的写法 return Object.assign(authInstance, { GoogleAuthProvider: GoogleAuthProvider }) } };
调整完成后无需修改signin.js的业务逻辑,原有的
new firebase.auth.GoogleAuthProvider()写法即可正常运行。
方案2:使用官方推荐的模块化标准写法
该方案适配Firebase V9+版本的树摇优化逻辑,可有效减小应用打包体积,是官方长期推荐的实现方式:
- 重构
firebase.prod.js的导入导出逻辑:
import { initializeApp } from "firebase/app"; import { getAuth, GoogleAuthProvider } from "firebase/auth"; import { getFirestore } from "firebase/firestore"; import { getStorage } from "firebase/storage"; const config = { apiKey: "AIzaSyASOat6CaIWxzwnepoGBHDpltnf9jH1QH0", authDomain: "cv-builder-c0429.firebaseapp.com", databaseURL: "https://cv-builder-c0429.firebaseio.com", storageBucket: "cv-builder-c0429.appspot.com", }; const firebaseApp = initializeApp(config); // 导出各服务实例和工具类 const auth = getAuth(firebaseApp); const db = getFirestore(firebaseApp); const storage = getStorage(firebaseApp); export { firebaseApp, auth, db, storage, GoogleAuthProvider };
- 调整
signin.js的业务调用逻辑:
import React from "react"; // 直接导入对应能力,无需通过Context取值 import { auth, GoogleAuthProvider } from "../firebase.prod"; export default function SignIn() { const googleSignIn = () => { // 直接使用导入的GoogleAuthProvider类初始化 const provider = new GoogleAuthProvider(); provider.addScope('profile'); provider.addScope('email'); auth.signInWithPopup(provider) .then((result) => { console.log(result) }).catch((error) => { console.log(error); }); }; return ( <button onClick={googleSignIn}>Sign in with google</button> ) };
注意:如果你的项目仍在使用React Context注入firebase实例,只需要把
auth和GoogleAuthProvider作为value传入Provider即可,不需要修改全局调用结构。
内容的提问来源于stack exchange,提问作者Job Oaikhenah
相关产品推荐
相关产品推荐

