У меня есть 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.
Как это предотвратить?





Вы можете использовать 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',
}