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

Ionic+Angular项目Firebase用户登出提示权限不足如何解决

错误根本原因

触发登出后,afAuth.signOut() 会先清除当前用户的登录态,但你之前在auth.service.ts里给user$流配置的switchMap返回的Firestore文档valueChanges()是持久化订阅,登录态消失后,这个还未取消的订阅仍会尝试请求Firestore资源。你的Firebase安全规则大概率限制了只有用户本人才能读自己的user文档,未登录状态没有访问权限,就会抛出权限不足的错误。


可行解决方案

方案1:登出前主动取消页面侧的订阅

你已经在app.component.ts中将订阅赋值给了this.appSub,只要在触发登出前先取消该订阅即可:

// app.component.ts 修改onLogout方法
//Logout Button
onLogout(){
    // 先取消Firestore文档的订阅,再执行登出
    this.appSub?.unsubscribe();
    this.authService.signOut();
}

方案2:给数据流添加自动销毁逻辑

在auth.service.ts内添加登出触发器,登出时自动停止所有Firestore监听,从数据流底层避免权限请求,适配多页面订阅用户数据的场景:
首先导入需要的rxjs依赖:

import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

修改service内部逻辑:

// auth.service.ts 新增私有属性
private unsubscribe$ = new Subject<void>();

// 修改user$的流配置
constructor(
  private afs: AngularFirestore,
  private afAuth: AngularFireAuth,
  private router: Router
) {
  this.user$ = this.afAuth.authState
    .pipe(
      switchMap( user => {
        if (user) {
          return this.afs.doc<User>(`user/${user.uid}`).valueChanges()
            .pipe(takeUntil(this.unsubscribe$)); // 登出时自动终止该订阅
        } else {
          return of(null);
        }
      })
    )
}

// 修改signOut登出方法
async signOut(){
  // 先触发所有关联订阅的终止信号
  this.unsubscribe$.next();
  this.unsubscribe$.complete();

  const loading = await this.loadingCtrl.create({
    spinner: 'crescent',
    showBackdrop: true
  });
  loading.present();

  this.afAuth.signOut()
    .then(() => {
      loading.dismiss();
      this.router.navigate(['/login']);
    }).catch(error => {
      console.log(error.message);
    });
}

方案3:补充错误捕获逻辑(辅助方案)

如果不想改动现有订阅逻辑,可以在用户数据订阅处添加错误捕获,直接忽略登出触发的权限错误:

// app.component.ts 修改订阅逻辑
this.appSub = this.authService.user$.subscribe({
  next: async user => {
    this.user = user;
    if(user) {
      this.userId = user.userId;
      try {
        this.userPhoto = user.userPhoto;
      } catch (error) {
        console.log('No User Photo');
      }
    }
  },
  error: (err) => {
    // 仅过滤登出触发的权限错误,其余错误仍正常抛出
    if(err.toString().includes('Missing or insufficient permissions')) {
      console.log('用户已登出,停止监听用户数据');
    } else {
      console.error(err);
    }
  }
});

内容的提问来源于stack exchange,提问作者John Paulo A. Geronimo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:06:03