[英]How to fix “TypeError: Cannot read property 'getIdToken' of null” on browser refresh, in angular firebase?
I am using firebase in angular 8 to authenticate the user both in frontend and backend.我在 angular 8 中使用 firebase 在前端和后端对用户进行身份验证。 To authenticate the user in the backend I need to send user Id token.要在后端验证用户身份,我需要发送用户 ID 令牌。
I am using firebase getIdToken to get the token and it works but partially.我正在使用 firebase getIdToken 来获取令牌,它可以工作但部分工作。 The error "TypeError: Cannot read property 'getIdToken' of null" occurs when I refresh the page.刷新页面时出现错误“TypeError:无法读取 null 的属性 'getIdToken'”。
I have tried to hard code the token to the getToken() method and it works even on refresh but that is not feasible, so I made the getToken method to return Observable.我试图将令牌硬编码到 getToken() 方法,它甚至在刷新时也能工作,但这是不可行的,所以我让 getToken 方法返回 Observable。
That observable is fetched in Http interceptor TokenInterceptorService, to add the token to all the requests.该 observable 在 Http 拦截器 TokenInterceptorService 中获取,以将令牌添加到所有请求中。
export class AuthService {
constructor(
public afs: AngularFirestore, // Inject Firestore service
public afAuth: AngularFireAuth, // Inject Firebase auth service
public router: Router,
public ngZone: NgZone // NgZone service to remove outside scope warning
) {}
// Other authentication methods for sign up etc.
// removed here for readability
getToken(): Observable<string> {
// getIdToken() returns promise so using 'from' to
// convert it to an Observable
const result = from(this.afAuth.auth.currentUser.getIdToken()
.then( token => {
console.log(token);
return token;
})
);
return result;
}
}
export class TokenInterceptorService implements HttpInterceptor {
constructor(private authService: AuthService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.authService.getToken()
.pipe(
switchMap(token => {
const newRequest = request.clone({
setHeaders: {Authorization: `JWT ${token}`}
});
return next.handle(newRequest);
})
);
}
}
I have seen similar questions and I am using that solution with some modification.我见过类似的问题,我正在使用该解决方案并进行一些修改。
I have even tried returning promise from getToken() method but that too doesn't work.我什至尝试从 getToken() 方法返回 promise 但这也不起作用。
getting the currentUser
is asynchronous, so it would be expected that initially it will be null
.获取currentUser
是异步的,因此预计最初它将是null
。 Like mentioned in documentation :就像文档中提到的那样:
Note:
currentUser
might also be null because theauth
object has not finished initializing.注意:currentUser
也可能是 null,因为auth
object 尚未完成初始化。
Instead you should be using authState
to get the current user.相反,您应该使用authState
来获取当前用户。 Then from the user you get from there, you can call getIdToken()
, which returns a promise.然后从你从那里得到的用户,你可以调用getIdToken()
,它返回一个 promise。 You can use from
there to convert it to an observable:您可以from
那里使用将其转换为可观察的:
getToken(): Observable<string | null> {
return this.afAuth.authState.pipe(
take(1),
switchMap((user) => {
if (user) {
return from(user.getIdToken())
}
return of(null);
})
)
}
Then in your interceptor, also do a check if token exists.然后在您的拦截器中,还要检查令牌是否存在。 If there is no user, it will return null
如果没有用户,则返回null
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.