Angular Universal does not prerender a module if resolved with firebase without authGuard

I’m making a web site with :

  • login page for admin auth
  • admin panel:
    • protected by firebase auth with canActivate AuthGuard
    • access to firebase realtime database for reading and writing via 2 resolvers (pages list, and upload list)
  • several pages :
    • access to firebase realtime database only for reading via 1 resolver (pages list)

When I prerender my project with Angular Universal, only the Login and Admin(+children) routes are prerendered. Children of PagesModule are not prerendered. The resolvers works well and the data is well passed in both modules.

I have investigated why and I found that if I attach the admin’s AuthGuard to the PagesModule, all the pages are well prerendered. But of course visitors can’t acces to my web site without credentials…

Someone could tell me how can I fix this ?

database.rules.json

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

app-routing.module

const routes: Routes = [
  {
    path: 'login',
    component: LoginComponent
  },
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
  },
  {
    path: '',
    loadChildren: () => import('./pages/pages.module').then(m => m.PagesModule)
  },
];

admin-routing.module

const routes: Routes = [
    {
        path: '',
        component: AdminComponent,
        resolve: { pages: PagesResolver, upload: UploadResolver },
        canActivate: [AuthGuard],
        children: [
            { path: '', component: AdminPagesComponent },
            { path: 'images', component: ImagesComponent },
            { path: '**', component: PageNotFoundComponent }
        ]
    },
];

pages-routing.module

const routes: Routes = [
    {
        path: '',
        component: PagesComponent,
        resolve: { pages: PagesResolver },
        canActivate: [PagesGuard], // Only there to try to solve my problem, should be deleted
        children: [
            { path: '', component: HomeComponent },
            { path: 'contact', component: ContactComponent },
            { path: 'devis', component: DevisComponent },
            { path: 'enseignes', component: EnseignesComponent },
            { path: 'vehicules', component: VehiculesComponent },
            { path: 'packaging', component: PackagingComponent },
            { path: 'plv', component: PlvComponent },
            { path: 'signaletique', component: SignaletiqueComponent },
            { path: 'about-us', component: AboutUsComponent },
            { path: '**', component: PageNotFoundComponent }
        ]
    }
];

AuthGuard

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.authService.authState()
      .pipe(
        map((isAuth) => {
          if (isAuth) {
            return true;
          } else {
            this.router.navigate(['/login']);
          }
        })
      )
  }

PagesResolver

resolve(): Observable<Page[]> {
    return this.pageDbService.getPages().snapshotChanges().pipe(
      map((pages) => {
        const newPages = pages.map(c => ({ key: c.payload.key, ...c.payload.val() as any }));
        this.pagesService.setPages(newPages)
        return newPages;
      }),
      take(1)
    );
  }

Source: Angular Questions

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.