Требуется получить новое значение после истечения срока действия токена аутентификации и при этом сохранять его горячим.В идеале в одной наблюдаемой переменной (без отдельного субъекта)
В настоящее время код выглядит следующим образом:
constructor(private angularFireAuth: AngularFireAuth) {}
private getAuthTokenResult(): Observable<firebase.auth.IdTokenResult> {
return this.angularFireAuth.authState.pipe(
switchMap(user => {
if (user) {
return from(user.getIdTokenResult(true));
} else {
return of(null);
}
})
);
}
public authToken$: Observable<string> = this.getAuthTokenResult().pipe(
map((result: firebase.auth.IdTokenResult) => {
if (new Date() >= new Date(result.expirationTime)) {
throw new Error('Token Expired');
} else {
return result.token;
}
}),
retryWhen(errors =>
errors.pipe(
tap(() => console.log('Token Expired. Getting New One...')),
delay(100),
take(3)
)
),
shareReplay(1)
) as ConnectableObservable<string>;
Но он не выполняет свою работу после истечения срока действия токена аутентификации - это новыйодин не получен.
Вот так выглядит зависимый сервисный метод
addProduct(
data: MerchantProductPartial
): Observable<MerchantProduct> {
return this.authService.authToken$.pipe(
switchMap(token => {
// console.log('_addProduct', token);
if (token) {
const endpoint = ``;
const httpOptions = {
headers: new HttpHeaders({
'Authorization': `Bearer ${token}`,
})
};
return this.http.post(endpoint, data, httpOptions);
}
else {
throw new Error('Authorization Token not provided.');
}
})
);
}
, а выполнение метода выглядит следующим образом
this.merchantService.addProduct({
name: 'New Test Product'
}).pipe(take(1)).subscribe(res => console.log('res:', res), err => console.log('err:', err))
РЕШЕНИЕ :
Если кого-то волнует решение - оно проще, чем я думал.Просто нужно использовать другой метод https://firebase.google.com/docs/reference/js/firebase.User#getIdToken, который автоматически обновляет недействительные токены ... Только не заставляйте его обновить ...
public authToken$: Observable<string> = this.angularFireAuth.authState.pipe(
switchMap(user: firebase.User => {
if (user) {
return from(user.getIdToken());
} else {
return of(null);
}
})
);