I am trying to make a login with google Auth on Firebase and when I login and try to load another component or a page I get the following. I have been trying to fix this bug for a whole day now and am very fed up. If anyone could help it would be appreciated.
My entire project is public at https://github.com/domilx/ProjetBocal-Angular
ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[NavbarComponent -> NavbarComponent -> NavbarComponent]:
NullInjectorError: No provider for NavbarComponent!
get@http://localhost:4200/vendor.js:120414:27
Here is my code
Navbar.component.html:
<div mat-elevation-z4>
<mat-toolbar color="primary">
<button routerLink="dashboard" mat-button aria-label="Home">
<mat-icon>home</mat-icon>
Projet Bocal
</button>
<span class="spacer-1"></span>
<button mat-button aria-label="Classroom">
<mat-icon>class</mat-icon>
Classroom
</button>
<button mat-button aria-label="Links">
<mat-icon>links</mat-icon>
Links
</button>
<span class="spacer-1"></span>
<button mat-button aria-label="Logout" *ngIf="auth.user$ | async as user" (click)="auth.signOut()">
<mat-icon>exit_to_app</mat-icon>
Logout, {{ user.displayName }}
</button>
<span class="spacer"></span>
<button routerLink="settings" mat-icon-button aria-label="settings" *ngIf="auth.user$ | async as user">
<mat-icon>settings</mat-icon>
</button>
</mat-toolbar>
</div>
Auth.service.ts
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/compat/firestore';
import { Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { User } from './user.model';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import { GoogleAuthProvider } from 'firebase/auth';
@Injectable({ providedIn: 'root' })
export class AuthService {
user$: Observable<User | null | undefined>;
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore,
private router: Router,
) {
this.user$ = this.afAuth.authState.pipe(
switchMap(user => {
if (user) {
return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
} else {
return of(null);
}
})
);
}
async googleSignin() {
const provider = new GoogleAuthProvider();
const credential = await this.afAuth.signInWithPopup(provider);
return this.updateUserData(credential.user);
}
async signOut() {
await this.afAuth.signOut();
return this.router.navigate(['/']);
}
private updateUserData(user) {
// Sets user data to firestore on login
const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`);
const data = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL
};
return userRef.set(data, { merge: true });
}
}
Auth.guard.ts
import { Injectable } from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
Router
} from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
import { tap, map, take } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService, private router: Router) {}
canActivate(next, state): Observable<boolean> {
return this.auth.user$.pipe(
take(1),
map(user => !!user), // <-- map to boolean
tap(loggedIn => {
if (!loggedIn) {
console.log('access denied');
this.router.navigate(['/']);
}
})
);
}
}
App.module.ts
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getAuth, provideAuth } from '@angular/fire/auth';
import { AngularFireModule } from '@angular/fire/compat';
import { AngularFireAuthModule } from '@angular/fire/compat/auth';
import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
import { AngularFirestoreModule } from '@angular/fire/compat/firestore/';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AboutComponent } from './components/pages/about/about.component';
import { ContactComponent } from './components/pages/contact/contact.component';
import { ClassroomComponent } from './components/pages/dashboard/classroom/classroom.component';
import { DashboardComponent } from './components/pages/dashboard/dashboard/dashboard.component';
import { LinksComponent } from './components/pages/dashboard/links/links.component';
import { HomeComponent } from './components/pages/home/home.component';
import { SettingsComponent } from './components/pages/settings/settings.component';
import { FooterComponent } from './components/shared/footer/footer.component';
import { NavbarComponent } from './components/shared/navbar/navbar.component';
import { MaterialModule } from './material.module';
import { AuthService } from './services/auth.service';
import { AuthGuard } from './services/auth.guard';
@NgModule({
declarations: [
AppComponent,
NavbarComponent,
FooterComponent,
AboutComponent,
SettingsComponent,
ContactComponent,
DashboardComponent,
HomeComponent,
ClassroomComponent,
LinksComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
RouterModule,
MaterialModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
AngularFireAuthModule,
AngularFirestoreModule,
AngularFireModule.initializeApp(environment.firebase),
AngularFireDatabaseModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideFirestore(() => getFirestore()),
provideAuth(() => getAuth()),
],
providers: [
AngularFirestoreModule,
AngularFireModule,
AngularFireAuthModule,
AngularFireDatabaseModule,
AuthGuard,
AuthService
],
bootstrap: [AppComponent]
})
export class AppModule { }
App-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SettingsComponent } from './components/pages/settings/settings.component';
import { AboutComponent} from './components/pages/about/about.component';
import { ContactComponent} from './components/pages/contact/contact.component';
import { DashboardComponent } from './components/pages/dashboard/dashboard/dashboard.component';
import { HomeComponent } from './components/pages/home/home.component';
import { AuthGuard } from './services/auth.guard';
const routes: Routes = [
{path:'', component:HomeComponent},
{path:'settings', component:SettingsComponent, canActivate: [AuthGuard] },
{path:'home', redirectTo:'/', pathMatch:'full'},
{path:'about', component:AboutComponent, canActivate: [AuthGuard] },
{path:'contact', component:ContactComponent, canActivate: [AuthGuard] },
{path:'dashboard', component:DashboardComponent, canActivate: [AuthGuard] },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
navbar.component.ts
import { Component, OnInit } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AuthService } from '../../../services/auth.service';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
constructor(public auth: AuthService) { }
ngOnInit(): void {
}
}
I found the issue.. In my dashboard.component.ts I had imported the NavBar for test a long while ago and forgot to remove it:
import { NavbarComponent } from './../../../shared/navbar/navbar.component';
import { Component, OnInit,EventEmitter,Output } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AuthService } from '../../../../services/auth.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
@Output() isLogout = new EventEmitter<void>()
constructor(NavbarComponent : NavbarComponent, public auth: AuthService) { }
ngOnInit(): void {
}
}
Just had to remove
NavbarComponent : NavbarComponent
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.