如何创建带名称的用户?Firebase注册%DISPLAY_NAME%问题排查
问题修复方案
你代码里有3处核心错误,直接导致无法创建带显示名称的用户、%DISPLAY_NAME%邮件标签读不到值:
- 变量覆盖:函数内写了
auth = document.getElementById('auth').value,直接把全局初始化好的Firebase Auth实例覆盖成了输入框的字符串值,后续所有Auth相关调用都会失效 - 语法与参数错误:
- 根本没从输入框读取
full_name(显示名/用户名)的值,却在写入数据库时直接引用未定义的full_name变量 createUserWithEmailAndPassword方法仅接收2个参数:邮箱、密码,你错误传入了3个参数,方法调用本身就不符合API规范
- 根本没从输入框读取
- 逻辑偏差:只把用户名存到了自定义的Realtime Database里,没有更新Firebase Auth内置的用户Profile。系统发送模板邮件时,读取的是Auth用户记录内置的
displayName字段,不会主动读取你存在自定义数据库里的字段,所以%DISPLAY_NAME%标签始终拿不到值。
修复操作
- 调整输入值读取逻辑,给表单字段命名时不要和Firebase SDK的实例名重名,补充读取显示名字段的逻辑
- 修正
createUserWithEmailAndPassword的传参,只传入邮箱和密码两个必填参数 - 用户创建成功后,先调用
updateProfile方法给当前Auth用户设置displayName,等profile更新完成后,再往数据库写入自定义用户数据,之后再触发邮件发送逻辑,确保模板能读取到名称字段
修正后的可运行代码
// 注意:auth 是你提前初始化完成的Firebase Auth实例,不要在函数内给它重新赋值 function register () { // 读取所有输入字段值,表单字段变量不要和SDK实例重名 const email = document.getElementById('email').value const password = document.getElementById('password').value const authCode = document.getElementById('auth').value // 原auth变量重命名,避免覆盖Auth实例 const fullName = document.getElementById('full_name').value // 补充读取显示名/用户名的输入值,原代码漏了这步 const favourite_song = document.getElementById('favourite_song').value const milk_before_cereal = document.getElementById('milk_before_cereal').value // 字段校验 if (!validate_email(email) || !validate_password(password)) { alert('邮箱或密码格式不符合要求') return } if (!validate_field(authCode) || !validate_field(favourite_song) || !validate_field(milk_before_cereal) || !validate_field(fullName)) { alert('请补全所有必填字段') return } // 调用注册方法,仅传邮箱、密码2个参数 auth.createUserWithEmailAndPassword(email, password) .then(async (userCredential) => { const user = userCredential.user // 直接从回调返回值取用户实例,比读auth.currentUser更可靠 // 核心步骤:更新Auth内置用户Profile,设置displayName,这是%DISPLAY_NAME%标签能读到值的前提 await user.updateProfile({ displayName: fullName }) // Profile更新完成后,再往Realtime Database写入自定义用户数据 const database_ref = database.ref() const user_data = { email : email, full_name : fullName, favourite_song : favourite_song, milk_before_cereal : milk_before_cereal, last_login : Date.now() } await database_ref.child('users/' + user.uid).set(user_data) // 如果需要发送验证邮件,放在这步之后调用即可,此时模板已经能正常读取到displayName // await user.sendEmailVerification() alert('用户创建成功') }) .catch(function(error) { alert(`操作失败:${error.message}`) }) }
补充说明
- 所有局部变量记得加
const/let声明,不要直接裸写变量名,否则会污染全局作用域,很容易出现这次的SDK实例被覆盖的问题 - 如果你是用Admin SDK在服务端处理用户创建逻辑,创建用户时直接传入
displayName参数即可,不要只把名称存在业务数据库 - 检查邮件模板里的
%DISPLAY_NAME%标签拼写,确认没有多余空格、拼写错误
内容的提问来源于stack exchange,提问作者Wenner Inc.
相关产品推荐
相关产品推荐

