You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过自定义REST API使用Firebase Auth实现登录?Cognito登录后导航栏不显示用户名

问题根因排查
  • 认证状态监听逻辑断层:Google登录走Firebase SDK的signInWithPopup流程,会自动触发afAuth.authState流推送登录态,所以导航栏能正常渲染用户信息;但Cognito登录流程仅调用了自建后端接口、往Firestore写入用户文档,完全没有触发Firebase认证状态的更新,afAuth.authState会一直保持未登录的null值,直接匹配模板里的anonymousUser分支。
  • 类属性名与模板读取规则不匹配:AuthService里定义的用户数据流属性是cuser$,但导航栏模板读取的是auth.user$,属性名不一致会导致永远取不到对应数据流。
  • 参考的示例逻辑没有完整落地:原示例的标准设计是将认证状态流与对应uid的Firestore用户文档做关联,不管是Firebase官方渠道还是自建的Cognito渠道,只要认证状态匹配到有效用户id,就能自动拉取对应用户数据渲染到页面,当前实现仅落地了Firebase渠道的状态关联部分。
具体整改步骤
  1. 统一AuthService的用户流属性名,把原本的cuser$改名为user$,和导航栏模板的读取逻辑保持一致。
  2. 重构用户数据流的绑定逻辑,兼容双渠道登录的状态感知:
    不要把用户流直接绑定死afAuth.authState,需要合并两个维度的状态源:
    • 原有的Firebase官方渠道(Google/Facebook/Twitter)的状态监听:拿到afAuth.authState的用户后,关联对应uid的Firestore文档拉取完整用户信息
    • 新增自建Cognito登录的状态触发器,当Cognito登录完成后,手动把当前登录用户推送到触发流里
      替换后的核心代码示例:
    import { BehaviorSubject, merge, of } from 'rxjs';
    import { switchMap } from 'rxjs/operators';
    
    // AuthService 类内部
    private cognitoLoginState$ = new BehaviorSubject<CUser | null>(null);
    user$: Observable<CUser | null>;
    
    constructor(private afAuth: AngularFireAuth, private httpClient: HttpClient, private afs: AngularFirestore) {
      // 合并双渠道的登录状态流
      this.user$ = merge(
        // 处理Firebase原生渠道的登录状态
        this.afAuth.authState.pipe(
          switchMap(fbUser => {
            if (!fbUser) return of(null);
            return this.afs.doc<CUser>(`users/${fbUser.uid}`).valueChanges();
          })
        ),
        // 处理Cognito自建渠道的登录状态
        this.cognitoLoginState$.asObservable()
      );
    }
    
  3. 补全Cognito登录成功后的状态推送逻辑:
    在doCognitoLogin方法的成功分支里,写入Firestore用户文档后,把构造好的Cognito用户对象推送到cognitoLoginState$流里,让导航栏的用户流感知到登录状态变化,修改后的核心代码:
    doCognitoLogin(email, password){
      // ... 省略接口参数构造逻辑
      return this.httpClient.post(this.apiUrl + '/signin', payload).pipe(
        map((response: any) => {
          const res = response;
          if (!res.error) { 
            const currentUser: CUser = {
              uid: email,
              email: email,
              displayName: email,
              photoURL: "",
              emailVerified: true
            };
            this.updateUserData(currentUser);
            // 主动推送登录状态到流中
            this.cognitoLoginState$.next(currentUser);
            return true; 
          } else { 
            console.log('wrong password'); 
            return false; 
          }
        })
      );
    }
    
  4. 完善登出逻辑的状态重置:
    原来的登出方法仅调用了afAuth.signOut(),需要补全Cognito渠道的状态清空,避免登出后残留旧的用户信息:
    logout() {
      this.afAuth.signOut();
      // 清空Cognito渠道的登录状态
      this.cognitoLoginState$.next(null);
    }
    
额外注意事项
  • 现有代码混用了旧版本rxjs的操作符导入方式(import 'rxjs/add/operator/switchMap'),和新版本rxjs的模块化导入规则不兼容,会导致流操作失效,建议统一换成从rxjs/operators导入对应操作符。
  • Cognito渠道写入Firestore的用户uid需要保证全局唯一,避免和Firebase原生登录生成的随机uid冲突,导致不同渠道的用户数据串用。

内容的提问来源于stack exchange,提问作者Amir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 14:36:01