如何修复Firebase Functions中“uid必须是非空字符串且不超128字符”错误
解决Firebase可调用云函数创建用户时的UID错误问题
看起来你遇到的这个UID错误,根源在于Promise链里的返回值传递出了问题——你在后续步骤里拿到的根本不是你期望的用户对象,而是Firestore写入操作的结果,导致UID变成了undefined。我来帮你拆解问题并修正代码:
核心错误点分析
Firestore
set()方法不返回用户对象
当你调用db.doc('users/'+user.uid).set(...)后,这个Promise的返回值是WriteResult(记录写入操作结果的对象),不是之前创建的user(Admin SDK的UserRecord)。所以下一个then里的user其实是WriteResult,它没有uid属性,导致uid = user.uid变成undefined,传给setCustomUserClaims就触发了「UID必须是非空字符串」的错误。setCustomUserClaims返回的是空白Promise
这个方法执行完成后只会返回Promise<void>,不会返回用户对象,所以后续调用user.sendEmailVerification()时,user是undefined,这一步也会报错。错误处理未正确抛出HttpsError
你的catch块只是创建了HttpsError对象,但没有抛出它,导致前端无法正确接收和解析错误信息。
修正后的云函数代码
const db = admin.firestore(); exports.createUser = functions.https.onCall((data, context) => { // 提前声明变量保存创建好的用户对象,避免在Promise链中丢失 let createdUser; return admin.auth().createUser({ email: data.email, password: data.password, displayName: data.displayName, }) .then(user => { // 把创建好的UserRecord存到变量里,后续步骤直接用 createdUser = user; return db.doc(`users/${user.uid}`).set({ email: data.email, displayName: data.displayName, type: data.type, organization: data.organization }); }) .then(() => { // 使用提前保存的createdUser的UID设置自定义权限 const customClaims = data.type === "admin" ? { isAdmin: true } : { isAdmin: false }; return admin.auth().setCustomUserClaims(createdUser.uid, customClaims); }) .then(() => { // 调用用户对象的验证邮件发送方法 return createdUser.sendEmailVerification(); }) .catch(error => { // 正确抛出HttpsError,让前端能捕获到清晰的错误信息 throw new functions.https.HttpsError('unknown', error.message, error); }); });
关键修改说明
- 新增
createdUser变量,在第一次创建用户后保存UserRecord实例,确保后续所有步骤都能拿到正确的用户信息。 - 调整Promise链的依赖逻辑,不再依赖上一步的返回值(因为
set和setCustomUserClaims都不返回用户对象),直接使用提前保存的createdUser。 - 优化自定义权限的写法,让代码更简洁。
- 修正错误处理,正确抛出HttpsError,包含错误类型、消息和原始错误详情,方便前端调试。
你的前端代码看起来没有问题,不过可以额外确认一下传递的type和organization参数是否为预期值,避免后续Firestore写入时出现其他意外问题。
内容的提问来源于stack exchange,提问作者Shei
相关产品推荐
相关产品推荐

