TypeScript中如何在函数外部获取Firebase创建的用户对象
解决Firebase创建用户后外部获取对象为undefined的问题
嘿,这个问题我太熟了——本质上是异步操作的执行顺序在搞鬼!咱们先拆解下你的代码问题,再给出具体的修复方案。
为什么会出现undefined?
你看,createUserWithEmailAndPassword是个异步方法,它返回的是一个Promise。你用.then()回调来处理成功后的用户对象,但.then()里的代码要等Firebase服务器完成用户创建后才会执行。而你在.then()外面的console.log(X)是同步代码,会先于回调执行,这时候X还没被赋值,自然就是undefined了。
你的原代码大概是这样的(我补全了省略的部分):
async saveProfile(){ const secondaryApp = this.firebase.initializeApp(this.config,"appname2"); var X; try { secondaryApp.auth().createUserWithEmailAndPassword(this.em, this.pwd) .then(function test(firebaseUser) { X = firebaseUser; // 这里能拿到X,因为回调是异步完成后执行的 console.log(X); // 省略secondaryApp的其他操作 }) // 这里的console.log会先跑,X还没赋值,所以是undefined console.log(X); } catch (error) { // 错误处理 } }
修复方案:正确处理异步结果
有两种优雅的方式来解决这个问题,核心都是确保你在异步操作完成后再去获取用户对象。
方案1:用await替代.then(推荐,代码更简洁)
因为你的saveProfile已经声明为async函数,直接用await等待Promise完成,代码会按顺序执行,等用户创建成功后再继续:
async saveProfile(){ const secondaryApp = this.firebase.initializeApp(this.config,"appname2"); let createdUser; try { // await会等待异步操作完成,直接拿到用户对象 createdUser = await secondaryApp.auth().createUserWithEmailAndPassword(this.em, this.pwd); // 这里可以直接使用createdUser,此时已经有值了 console.log(createdUser); // 要在函数外部获取这个对象?让函数返回它就行 return createdUser; } catch (error) { console.error("创建用户失败:", error); // 抛出错误,让调用者可以处理 throw error; } finally { // 记得销毁secondaryApp,避免重复初始化的问题 await secondaryApp.delete(); } }
然后外部调用的时候,也要用await或者.then来获取返回值:
// 方式一:在async函数里用await async function useCreatedUser() { try { const user = await this.saveProfile(); console.log("外部获取的用户对象:", user); // 这里就能拿到正确的值了 } catch (err) { // 处理错误 } } // 方式二:用.then链式调用 this.saveProfile() .then(user => console.log("外部获取的用户对象:", user)) .catch(err => console.error("调用出错:", err));
方案2:保留.then,但正确返回Promise
如果你习惯用.then的写法,那要确保函数返回Promise,这样外部可以通过.then获取用户对象:
saveProfile(){ const secondaryApp = this.firebase.initializeApp(this.config,"appname2"); // 直接返回Promise链 return secondaryApp.auth().createUserWithEmailAndPassword(this.em, this.pwd) .then(firebaseUser => { console.log("创建成功的用户:", firebaseUser); // 做其他操作后返回用户对象 secondaryApp.delete(); return firebaseUser; }) .catch(error => { console.error("创建用户失败:", error); secondaryApp.delete(); throw error; // 抛出错误让外部处理 }); } // 外部调用 this.saveProfile() .then(user => console.log("外部获取的用户对象:", user)) .catch(err => console.error("调用出错:", err));
额外提醒
- 一定要记得删除
secondaryApp:Firebase不允许重复初始化同名的App,所以用完后用secondaryApp.delete()销毁它,避免后续报错。 - 错误处理不能少:创建用户可能会遇到邮箱已存在、密码强度不够等错误,一定要用
try/catch或者.catch捕获处理。
内容的提问来源于stack exchange,提问作者Semah
相关产品推荐
相关产品推荐

