无法读取 null 的 属性 'uid'
Cannot read property 'uid' of 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.log(res),
error => console.log(error)
);
}
问题:
当我在页面之间重定向时它工作正常,但是在刷新页面之后 getData()
方法在 authState
回调分配当前身份验证之前被调用并且实际上 userId()
方法 return null.
如何预防?
您可以使用身份验证 guard or a 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],
}
或此解析器将在加载路由之前设置当前用户 ID:
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',
}
我有我的 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()
方法 return null.
如何预防?
您可以使用身份验证 guard or a 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],
}
或此解析器将在加载路由之前设置当前用户 ID:
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',
}