使用AngularFireAuth登录后调用getUser返回undefined问题求助
解决方案
1. 重构AuthService的getUser方法,基于Firebase Auth异步流实现
Firebase登录是异步操作,同步获取用户会因为状态未更新返回undefined,需要通过监听authState或userChanges这两个Observable来实时获取用户状态:
import { AngularFireAuth } from '@angular/fire/auth'; import { Observable, of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class AuthService { constructor(private afAuth: AngularFireAuth) {} // 返回用户Observable,实时响应登录状态变化 getUser(): Observable<any> { return this.afAuth.authState.pipe( switchMap(user => { if (user) { // 如果需要同时拉取Firestore用户文档,可在此添加查询逻辑 // return this.firestore.collection('users').doc(user.uid).valueChanges(); return of(user); } else { return of(null); } }) ); } // 保持登录方法的异步特性,返回Promise emailAndPasswordSignIn(email: string, password: string): Promise<any> { return this.afAuth.signInWithEmailAndPassword(email, password); } }
2. 登录后通过订阅获取用户,避免同步调用
在登录组件中,不要在登录完成后直接同步调用getUser(),而是在登录Promise的回调中订阅用户Observable,确保拿到已更新的用户状态:
// 登录组件代码 onLogin(email: string, password: string) { this.authService.emailAndPasswordSignIn(email, password) .then(() => { // 登录完成后订阅用户信息 this.authService.getUser().subscribe(user => { if (user) { // 执行数据库查询与页面路由 this.router.navigate(['/dashboard']); this.firestore.collection('users').doc(user.uid).get().then(doc => { // 处理用户文档数据 }); } }); }) .catch(error => { console.error('登录失败:', error); }); }
3. 可选:用async/await简化异步流程
如果习惯使用async/await语法,可改写为:
async onLogin(email: string, password: string) { try { await this.authService.emailAndPasswordSignIn(email, password); // 订阅用户状态,确保拿到有效数据 this.authService.getUser().subscribe(async user => { if (user) { this.router.navigate(['/dashboard']); const userDoc = await this.firestore.collection('users').doc(user.uid).get().toPromise(); // 处理用户文档数据 } }); } catch (error) { console.error('登录失败:', error); } }
核心原因说明
Firebase的signInWithEmailAndPassword是异步操作,即使Promise已resolve,Auth状态的内存更新可能存在微小延迟,同步调用getUser()会刚好错过状态更新导致返回undefined。通过监听authStateObservable,能确保在Auth状态完成更新后立即获取到有效用户信息。
内容的提问来源于stack exchange,提问作者Willem Ghijsen
相关产品推荐
相关产品推荐

