Невозможно прочитать свойство uid со значением null

У меня есть 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.info(res),
     error => console.info(error)
   );
}

Проблема: Когда я перенаправляю между страницами, он работает нормально, но после обновления страницы метод getData() вызывается до того, как обратный вызов authState назначает текущую аутентификацию и, по сути, метод userId() возвращает значение null.

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

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
345
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать auth сторожить или решатель, примерно так:

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

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

Другие вопросы по теме