【问题标题】:Cannot read property 'uid' of null无法读取 null 的属性“uid”
【发布时间】:2019-02-05 08:15:48
【问题描述】:

我有我的 AuthService,我订阅了 authState。

@Injectable()
export class AuthService {

    private user: User = null;

    constructor(private afAuth: AngularFireAuth) {
       const sub$ = this.afAuth.authState.subscribe(auth => {
       this.user = auth;
    });

   get userId(): string {
       return this.user.uid;
   }
}

现在在其他组件中,我想获取属于当前登录用户的对象,所以我创建了一个服务:

@Injectable()
export class SomeService{

    constructor(private readonly afs: AngularFirestore,
                private auth: AuthService) {
    }

    ...

     getByCurrentUser(): Observable<any> {
         return this.afs.collection<any>('my-path',
            ref => ref
            .where('userId', '==', this.auth.userId)).valueChanges();
     }
}

在组件中我订阅了这个方法:

...

ngOnInit() {
   this.getData();
}

private getData(): void {
   this.testService.getByCurrentUser().subscribe(
     res => console.log(res),
     error => console.log(error)
   );
}

问题: 当我在页面之间重定向时它工作正常,但是在刷新页面之后getData() 方法在authState 回调分配当前身份验证之前调用,实际上userId() 方法返回null。

如何预防?

【问题讨论】:

    标签: angular firebase firebase-authentication angularfire2


    【解决方案1】:

    您可以使用身份验证 guardresolver,如下所示:

    除非用户通过身份验证,否则此守卫将阻止加载路由。

    export class AdminAuthGuard implements CanActivate {
    
      constructor(private auth: AngularFireAuth) {}
    
      canActivate(): Observable<boolean> | Promise<boolean> | boolean {
        return this.auth.authState.pipe(map((auth) => {
          if (!auth) {
            // Do stuff if user is not logged in
            return false;
          }
          return true;
        }),
        take(1));
      }
    }
    

    在你的路由模块中使用它:

    {
      path: 'yourPath',
      component: YourComponent,
      canActivate: [AdminAuthGuard],
    }
    

    或者这个解析器会在路由加载前设置当前用户ID:

    export class UserIdResolver implements Resolve<boolean> {
      constructor(
        private auth: AngularFireAuth,
        private authService: AuthService,
      ) {}
    
      resolve(): Observable<boolean> {
        return this.auth.user.pipe(map((user) => {
          if (user) {
            this.authService.setCurrentUser(user.uid); // set the current user
            return true;
          }
          this.authService.setCurrentUser(null);
          return false;
        }), take(1));
      }
    } 
    

    在你的路由模块中使用它:

    {
      path: 'yourPath',
      component: YourComponent,
      resolve: [UserIdResolver],
      runGuardsAndResolvers: 'always',
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-14
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多