MongoDB与Firebase/Firestore后端集成及用户信息修改uid报错排查
Firebase Auth/Firestore 用户信息修改接口UID报错解决方案
问题背景
为减少后端开发工作量,计划集成Firebase/Firestore实现用户修改密码、邮箱、地址、手机号功能,复用Firebase的验证机制。已完成firebase.js配置和userController.js接口编写,但Postman调用时出现两类UID相关报错:
{ "status": "error", "message": "The uid must be a non-empty string with at most 128 characters." }{ "status": "error", "message": "The uid is not defined." }
相关代码
firebase.js配置文件
const admin = require('firebase-admin'); const serviceAccount = require('./firebase.json'); const config = { credential: admin.credential.cert(serviceAccount), }; const firebase = admin.apps.length ? admin.app() : admin.initializeApp(config); module.exports = firebase;
userController.js文件
const asyncHandler = require('express-async-handler'); const firebase = require('../firebase'); const Cart = require('../models/cartModel'); const AppError = require('../utilities/appError'); const User = require('../models/userModel'); const firestore = firebase.firestore(); exports.changePassword = asyncHandler(async (req, res, next) => { const { newPassword } = req.body; const user = await User.findById(req.user.id).select('+password'); await firebase.auth().updateUser(user.uid, { password: newPassword, }); res.status(200).json({ message: 'Password changed successfully' }); next(); }); exports.changeEmail = asyncHandler(async (req, res, next) => { const { newEmail } = req.body; const user = req.user; console.log(uid); await firebase.auth().updateUser(user.uid, { email: newEmail, }); // Send email verification await firebase.auth().sendEmailVerification({ email: newEmail, }); res.status(200).json({ message: 'Email changed successfully. Please verify your new email address.', }); next(); }); exports.changeAddress = asyncHandler(async (req, res, next) => { const { newAddress } = req.body; const userId = req.user.id; await firestore.collection('users').doc(userId).update({ address: newAddress, }); res.status(200).json({ message: 'Address changed successfully' }); }); exports.changePhoneNumber = asyncHandler(async (req, res, next) => { const { newPhoneNumber } = req.body; const userId = req.user.id; await firestore.collection('users').doc(userId).update({ phoneNumber: newPhoneNumber, }); res.status(200).json({ message: 'Phone number changed successfully' }); });
报错原因及修复方案
报错1:The uid must be a non-empty string with at most 128 characters.
- 原因:传入Firebase Auth的
user.uid为空、非字符串类型,或者长度不符合要求(Firebase UID要求是1-128位的字符串),大概率是MongoDB的用户文档中uid字段未正确存储Firebase生成的合法UID。 - 修复:
- 检查MongoDB用户数据,确保
uid字段存储的是Firebase Auth返回的合法UID字符串。 - 在
changePassword方法中添加UID校验逻辑,提前拦截非法值:
exports.changePassword = asyncHandler(async (req, res, next) => { const { newPassword } = req.body; const user = await User.findById(req.user.id).select('+password'); // 新增UID合法性校验 if (!user.uid || typeof user.uid !== 'string' || user.uid.length === 0 || user.uid.length > 128) { return next(new AppError('无效的Firebase UID', 400)); } await firebase.auth().updateUser(user.uid, { password: newPassword, }); res.status(200).json({ message: 'Password changed successfully' }); }); - 检查MongoDB用户数据,确保
报错2:The uid is not defined.
- 原因:
changeEmail方法中存在未声明的console.log(uid);语句,uid变量未定义导致运行时错误。 - 修复:删除无效的
console.log语句,或改为打印正确的user.uid,同时添加UID校验:exports.changeEmail = asyncHandler(async (req, res, next) => { const { newEmail } = req.body; const user = req.user; // 修正日志语句,或直接删除 console.log(user.uid); // 新增UID合法性校验 if (!user.uid || typeof user.uid !== 'string' || user.uid.length === 0 || user.uid.length > 128) { return next(new AppError('无效的Firebase UID', 400)); } await firebase.auth().updateUser(user.uid, { email: newEmail, }); // Send email verification await firebase.auth().sendEmailVerification({ email: newEmail, }); res.status(200).json({ message: 'Email changed successfully. Please verify your new email address.', }); });
额外优化建议
- 统一校验逻辑:封装公用的UID校验函数,避免重复代码:
在需要的地方调用:const validateFirebaseUid = (uid) => { return !!uid && typeof uid === 'string' && uid.length > 0 && uid.length <= 128; };if (!validateFirebaseUid(user.uid)) { return next(new AppError('无效的Firebase UID', 400)); } - Firestore文档ID一致性:如果Firestore用户文档是用Firebase UID作为ID存储的,
changeAddress和changePhoneNumber方法中需将req.user.id替换为user.uid,否则会出现找不到文档的问题。 - 增强错误捕获:为Firebase接口调用添加针对性错误捕获,返回更清晰的提示:
try { await firebase.auth().updateUser(user.uid, { password: newPassword, }); } catch (err) { return next(new AppError(`Firebase操作失败:${err.message}`, 400)); }
内容的提问来源于stack exchange,提问作者michaelzxvi
相关产品推荐
相关产品推荐

