Невозможно прочитать свойство 'uid' из null - PullRequest
0 голосов
/ 30 августа 2018

У меня есть мой 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() метод возвращает ноль.

Как это предотвратить?

1 Ответ

0 голосов
/ 30 августа 2018

Вы можете использовать auth guard или resolver , что-то вроде этого:

Этот сторож предотвратит загрузку маршрута, если пользователь не аутентифицирован.

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],
}

или этот преобразователь будет устанавливать текущий идентификатор пользователя до загрузки маршрута:

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',
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...