Firebase Auth如何正确判断用户首次Google登录
核心问题纠正
你之前访问auth.AdditionalUserInfo的写法存在本质认知偏差:
AdditionalUserInfo不是auth实例上挂载的运行时属性,它是Firebase Auth登录流程返回结果的嵌套数据类型定义,本身不是可直接访问的对象,所以TypeScript和IDE提示不存在是完全符合预期的。- 你项目使用的是Firebase v8版本,官方定义中,
signInWithPopup等登录方法会返回Promise<firebase.auth.UserCredential>对象,这个对象的additionalUserInfo属性,才是实际运行时存储isNewUser等用户附加信息的位置。
正确实现首次登录判断的步骤
1. 修改登录函数的异步处理逻辑
你当前的login函数没有等待signInWithPopup的异步执行完成,存在两个连带问题:
- 无法获取包含首次登录标识的结果对象
- 登录还未完成时就调用
getTodos,此时auth.currentUser可能为null,直接访问displayName字段会抛错
将原login函数替换为如下异步实现:
async function login() { try { // 等待登录弹窗完成授权,拿到完整的用户凭证对象 const userCredential = await auth.signInWithPopup(googleProvider); // 从凭证对象中提取用户附加信息(存在为null的可能,需加可选链判断) const userExtInfo = userCredential.additionalUserInfo; // 首次登录判断逻辑 if (userExtInfo?.isNewUser) { // 在此处编写首次登录的自定义逻辑,比如初始化用户基础文档、弹出欢迎引导等 console.log('当前用户为首次通过Google账号完成登录'); } // 登录流程完全就绪后再执行后续页面逻辑 signedin = true; getTodos(); } catch (error) { // 处理弹窗被拦截、用户取消授权等登录失败场景 console.error('Google登录流程异常', error); } }
2. 类型引用的正确方式
如果你需要在TypeScript中显式标注AdditionalUserInfo类型,不需要从auth实例上获取,直接从模块导入类型即可:
// 在文件顶部导入类型定义(纯类型导入不会增加运行时包体积) import type { AdditionalUserInfo } from 'firebase/auth'; // 后续可以直接用该类型标注变量 let cachedUserExtInfo: AdditionalUserInfo | null = null;
关键注意点
additionalUserInfo字段并非一定存在,取值时必须通过可选链做空值判断,避免空指针报错- 所有依赖
auth.currentUser的逻辑,必须等待对应登录方法的Promise完成resolve后再执行,避免出现时序竞态
内容的提问来源于stack exchange,提问作者noctis_atrae
相关产品推荐
相关产品推荐

