使用Firebase Admin调用getAuth()出现getProvider未定义错误求助
问题:Node.js后端使用Firebase Admin时调用getAuth()触发TypeError错误
错误栈
TypeError: Cannot read properties of undefined (reading 'getProvider') at Object._getProvider (/Users/mnjuhn/Projects/CloudMedic/src/routes/functions/node_modules/@firebase/app/dist/index.cjs.js:276:10) at getAuth (/Users/mnjuhn/Projects/CloudMedic/src/routes/functions/node_modules/@firebase/auth/dist/node/totp-fe65684a.js:8197:24) at Object.<anonymous> (/Users/mnjuhn/Projects/CloudMedic/src/routes/functions/app.js:26:14) at Module._compile (node:internal/modules/cjs/loader:1376:14) at Module._extensions..js (node:internal/modules/cjs/loader:1435:10) at Module.load (node:internal/modules/cjs/loader:1207:32) at Module._load (node:internal/modules/cjs/loader:1023:12) at Module.require (node:internal/modules/cjs/loader:1235:19) at require (node:internal/modules/helpers:176:18) at Object.<anonymous> (/Users/mnjuhn/Projects/CloudMedic/src/routes/functions/user.js:2:36)
我的Firebase应用初始化代码
var functions = require("firebase-functions"); const { getDatabase, ref, set, child, push, update } = require("firebase/database"); const { getAuth, onAuthStateChanged, signInWithEmailAndPassword, initializeAuth, createUserWithEmailAndPassword } = require("firebase/auth"); const { doc, setDoc } = require('firebase/firestore'); const { getFirestore, Timestamp, FieldValue, Filter } = require('firebase-admin/firestore'); const { initializeApp } = require('firebase-admin/app'); const http = require('http'); const express = require('express'); var bodyParser = require('body-parser'); var router = express.Router(); var cors = require('cors'); const firebaseConfig = { // 隐藏的配置信息 }; const admin = initializeApp(firebaseConfig); const db = getFirestore(admin); const auth = getAuth(admin); // 触发错误的代码行 const app = express(); app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.json({limit:'5mb'})); app.use(bodyParser.urlencoded({extended:true})); var jsonParser = bodyParser.json(); async function signIn(email, password) { signInWithEmailAndPassword(email, password).then((userCredential) => { // 登录成功 console.log("TEST Signed in"); return userCredential; }).catch((error) => { const errorCode = error.code; const errorMessage = error.message; console.log("Error Signing in"); console.log(error.message); throw error; }); } exports.db = db; exports.app = app; exports.signIn = signIn; exports.admin = admin; exports.auth = auth; exports.createUserWithEmailAndPassword = createUserWithEmailAndPassword;
创建用户代码
var constants = require('./constants.js'); const { db, app, signIn, admin } = require('./app'); var cors = require('cors'); const { Timestamp } = require('firebase/firestore'); function signup(req, res) { birthDate = new Date(Number(req.query.birthDate)); var user = { id: db.collection("users").doc().id, email: req.query.email, password: req.query.password, firstName: req.query.firstName, lastName: req.query.lastName, gender: req.query.gender, birthDate: birthDate, timestamp: new Date() }; const auth = app.auth; app.createUserWithEmailAndPassword(auth, req.query.email, req.query.password).then((userCredential) => { // 注册成功 const user = userCredential.user; console.log("USER SUCCESSFULLY CREATED"); }).catch((error) => { const errorCode = error.code; const errorMessage = error.message; console.log("ERROR CREATING USER"); // .. }); return db.collection('users').doc(user.id).set(user).then(snapshot => { console.log(user); return res.status(200).json({status:200, message:"ADDED USER"}); }).catch(err => { console.log(err); return res.status(200).json({status:200, message:"ERROR ADDING USER"}); }); } module.exports = { signup: signup, };
问题
请问该源于const auth = getAuth(admin);的错误是否由使用Firebase Admin导致?
解答
这个错误确实是混用Firebase客户端SDK和Admin SDK导致的:
getAuth()是Firebase客户端SDK(firebase/auth)的API,它要求传入的是客户端SDK初始化的App实例(即通过firebase/app的initializeApp创建的实例),但你传入的是Firebase Admin SDK初始化的admin实例,两者属于不同的SDK体系,结构不兼容,因此会触发Cannot read properties of undefined (reading 'getProvider')错误。后端服务应该使用Firebase Admin SDK处理用户认证,正确的做法是:
- 移除客户端SDK的
firebase/auth相关导入 - 使用Admin SDK的
admin.auth()或getAuth(admin)(Admin SDK v10+支持)获取Auth实例 - 使用Admin SDK的
createUser方法创建用户,而非客户端的createUserWithEmailAndPassword
- 移除客户端SDK的
修正后的代码示例
调整app.js中的认证相关代码
// 移除客户端auth的导入 // const { getAuth, onAuthStateChanged, signInWithEmailAndPassword, initializeAuth, createUserWithEmailAndPassword } = require("firebase/auth"); // 导入Admin SDK的auth模块 const { getAuth } = require('firebase-admin/auth'); const admin = initializeApp(firebaseConfig); const db = getFirestore(admin); const auth = getAuth(admin); // 现在使用Admin SDK的getAuth,传入admin实例合法 // 替换signIn函数为Admin SDK的认证逻辑(后端推荐通过ID令牌验证) async function signIn(idToken) { try { const decodedToken = await admin.auth().verifyIdToken(idToken); console.log("用户令牌验证成功", decodedToken.uid); return decodedToken; } catch (error) { console.log("令牌验证失败", error.message); throw error; } } // 导出Admin SDK的createUser方法 exports.createUser = admin.auth().createUser;
调整signup函数
function signup(req, res) { birthDate = new Date(Number(req.query.birthDate)); // 不要存储明文密码,Admin SDK会自动处理哈希存储 const userData = { email: req.query.email, firstName: req.query.firstName, lastName: req.query.lastName, gender: req.query.gender, birthDate: birthDate, timestamp: new Date() }; // 使用Admin SDK创建用户 admin.auth().createUser({ email: req.query.email, password: req.query.password, displayName: `${req.query.firstName} ${req.query.lastName}` }).then((userRecord) => { console.log("USER SUCCESSFULLY CREATED", userRecord.uid); // 将Admin生成的用户ID关联到数据库记录 userData.id = userRecord.uid; return db.collection('users').doc(userRecord.uid).set(userData); }).then(() => { return res.status(200).json({status:200, message:"ADDED USER"}); }).catch(err => { console.log(err); return res.status(400).json({status:400, message:"ERROR ADDING USER", error: err.message}); }); }
关键注意事项
- 后端绝对不要存储用户明文密码,Admin SDK创建用户后会自动处理密码哈希存储
- 后端认证建议通过客户端传入的ID令牌进行验证,而非直接处理密码
- 避免同时混用客户端SDK和Admin SDK的认证模块,防止API冲突
内容的提问来源于stack exchange,提问作者MattJ
相关产品推荐
相关产品推荐

