每次检查时,Auth Guard都会调用auth服务构造函数

时间:2019-09-15 09:32:41

标签: angular

我有auth服务,如果有用户,该服务会创建一个可观察的user $,否则它将从firestore中获取文档,如果没有则返回null,还有其他登录和创建用户方法。

此身份验证服务正在注入到两个防护AuthGuard和LoggedInAuthGuard及各种组件中

但是我观察到,每当路由发生变化时,就会调用auth保护,每次都会调用auth服务构造函数

我尝试通过将代码移入AppModule来删除AppRoutingModule,但Guard每次调用它们时仍在调用服务构造函数

AuthService

imports...
@Injectable({
  providedIn: 'root'
})

export class AuthService {

  user$: Observable<User>;
  private authError = new BehaviorSubject<string>('');
  authError$ = this.authError.asObservable();
  doc: AngularFirestoreDocument<User>;

  constructor(
    private afAuth: AngularFireAuth,
    private afs: AngularFirestore,
    private router: Router
  ) {
    // Get the auth state, then fetch the Firestore user document or 
return null
    this.user$ = this.afAuth.authState.pipe(
      switchMap(user => {
        // Logged in
        if (user) {
          // Test when multiple request are being sent
          console.log(user.toJSON(), new Date().getMilliseconds());           this.doc = this.afs.doc<User>(`users/${user.uid}`);
          return this.doc.valueChanges();
        } else {
          // Logged out
          return of(null);
        }
      })
    );
  }

// other Login & create user methos

AuthGuard

imports...

@Injectable({
  providedIn: 'root'
})

export class AuthGuard implements CanActivate {
  constructor(
    private auth: AuthService,
    private router: Router
  ) { }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> {
    return this.auth.user$.pipe(
      take(1),
      map(user => !!user), // <-- map to boolean
      tap(loggedIn => {
        if (!loggedIn) {
          this.router.navigate(['/login']);
        }
      })
    );
  }
}

LoggedInAuthGuard

imports
@Injectable({
  providedIn: 'root'
})
export class LoggedInAuthGuard implements CanActivate {
  constructor(
    private auth: AuthService,
    private router: Router
  ) { }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> {
      return this.auth.user$.pipe(
        take(1),
        map(user => !!user),
        tap(loggedIn => {
          if(loggedIn) {
            this.router.navigate(['/account']);
          }
        })
      );
  }
}

AppModule

imports ....

@NgModule({
  decalaration:[...],
  imports: [...,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})

AppRoutingModule

imports ...

const routes: Routes = [
  {
    path: '',
    redirectTo: '/dashboard',
    pathMatch: 'full'
  },
  {
    path: 'login',
    component: LoginComponent,
    canActivate: [LoggedInAuthGuard]
  },
  {
    path: 'register',
    component: RegisterComponent,
    canActivate: [LoggedInAuthGuard]
  },
  {
    path: 'dashboard',
    component: DashboardComponent
  },
  {
    path: 'mylist',
    component: MyListComponent,
    canActivate: [AuthGuard]
  },
  {
    path: 'explore',
    component: ExploreComponent
  },
  {
    path: 'contribute',
    component: ContributeComponent,
    canActivate: [AuthGuard]
  },
  {
    path: 'account',
    component: AccountComponent,
    canActivate: [AuthGuard]
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

在控制台中,我记录了来自Firestore的数据,我希望它仅运行一次,但是每次更改时都会出错

GitHub-https://github.com/patel-malav/Project-Birdie/tree/website-2.0

控制台图片-https://github.com/patel-malav/Project-Birdie/blob/website-2.0/website-revamp/Screenshot%20from%202019-09-15%2014-56-55.png

0 个答案:

没有答案