How to use Firebase auth in Angular
Firebase Authentication provides a complete identity solution with support for email/password, social providers, and phone authentication. As the creator of CoreUI, I’ve integrated Firebase auth in countless Angular applications serving enterprise clients.
The most maintainable approach is to use AngularFire, the official Angular library for Firebase, with a custom auth service and route guards.
Install Dependencies
Install AngularFire and Firebase:
npm install @angular/fire firebase
ng add @angular/fire
During setup, select Authentication when prompted for Firebase features.
Configure Firebase
Add your Firebase config in src/environments/environment.ts:
export const environment = {
production: false,
firebase: {
apiKey: 'your-api-key',
authDomain: 'your-project.firebaseapp.com',
projectId: 'your-project-id',
storageBucket: 'your-project.appspot.com',
messagingSenderId: '123456789',
appId: 'your-app-id'
}
}
Initialize Firebase
Update src/app/app.config.ts (standalone) or app.module.ts:
import { ApplicationConfig, importProvidersFrom } from '@angular/core'
import { provideFirebaseApp, initializeApp } from '@angular/fire/app'
import { provideAuth, getAuth } from '@angular/fire/auth'
import { environment } from '../environments/environment'
export const appConfig: ApplicationConfig = {
providers: [
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAuth(() => getAuth())
]
}
For module-based apps:
import { NgModule } from '@angular/core'
import { provideFirebaseApp, initializeApp } from '@angular/fire/app'
import { provideAuth, getAuth } from '@angular/fire/auth'
import { environment } from '../environments/environment'
@NgModule({
imports: [
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAuth(() => getAuth())
]
})
export class AppModule {}
Create Auth Service
Generate an auth service:
ng generate service services/auth
In src/app/services/auth.service.ts:
import { Injectable } from '@angular/core'
import {
Auth,
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
signOut,
GoogleAuthProvider,
signInWithPopup,
User,
user
} from '@angular/fire/auth'
import { Observable } from 'rxjs'
@Injectable({
providedIn: 'root'
})
export class AuthService {
user$: Observable<User | null>
constructor(private auth: Auth) {
this.user$ = user(this.auth)
}
async loginWithEmail(email: string, password: string): Promise<void> {
try {
await signInWithEmailAndPassword(this.auth, email, password)
} catch (error: any) {
throw new Error(this.getErrorMessage(error.code))
}
}
async registerWithEmail(email: string, password: string): Promise<void> {
try {
await createUserWithEmailAndPassword(this.auth, email, password)
} catch (error: any) {
throw new Error(this.getErrorMessage(error.code))
}
}
async loginWithGoogle(): Promise<void> {
const provider = new GoogleAuthProvider()
try {
await signInWithPopup(this.auth, provider)
} catch (error: any) {
throw new Error(this.getErrorMessage(error.code))
}
}
async logout(): Promise<void> {
await signOut(this.auth)
}
private getErrorMessage(code: string): string {
switch (code) {
case 'auth/user-not-found':
return 'No user found with this email'
case 'auth/wrong-password':
return 'Incorrect password'
case 'auth/email-already-in-use':
return 'Email already registered'
case 'auth/weak-password':
return 'Password should be at least 6 characters'
case 'auth/invalid-email':
return 'Invalid email address'
default:
return 'Authentication error occurred'
}
}
}
Create Login Component
Generate a login component:
ng generate component components/login
In src/app/components/login/login.component.ts:
import { Component } from '@angular/core'
import { Router } from '@angular/router'
import { AuthService } from '../../services/auth.service'
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent {
email = ''
password = ''
error = ''
loading = false
constructor(
private authService: AuthService,
private router: Router
) {}
async onLogin(): Promise<void> {
this.loading = true
this.error = ''
try {
await this.authService.loginWithEmail(this.email, this.password)
this.router.navigate(['/dashboard'])
} catch (error: any) {
this.error = error.message
} finally {
this.loading = false
}
}
async onGoogleLogin(): Promise<void> {
this.loading = true
this.error = ''
try {
await this.authService.loginWithGoogle()
this.router.navigate(['/dashboard'])
} catch (error: any) {
this.error = error.message
} finally {
this.loading = false
}
}
}
In login.component.html:
<div class="login-container">
<h2>Login</h2>
<form (ngSubmit)="onLogin()">
<div class="form-group">
<label for="email">Email</label>
<input
type="email"
id="email"
[(ngModel)]="email"
name="email"
required
/>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
type="password"
id="password"
[(ngModel)]="password"
name="password"
required
/>
</div>
<div *ngIf="error" class="error">{{ error }}</div>
<button type="submit" [disabled]="loading">
{{ loading ? 'Logging in...' : 'Login' }}
</button>
</form>
<div class="divider">OR</div>
<button (click)="onGoogleLogin()" [disabled]="loading" class="google-btn">
Sign in with Google
</button>
</div>
Create Auth Guard
Generate a guard to protect routes:
ng generate guard guards/auth
In src/app/guards/auth.guard.ts:
import { Injectable } from '@angular/core'
import { Router } from '@angular/router'
import { Auth, user } from '@angular/fire/auth'
import { Observable } from 'rxjs'
import { map, take } from 'rxjs/operators'
@Injectable({
providedIn: 'root'
})
export class AuthGuard {
constructor(
private auth: Auth,
private router: Router
) {}
canActivate(): Observable<boolean> {
return user(this.auth).pipe(
take(1),
map(currentUser => {
if (currentUser) {
return true
}
this.router.navigate(['/login'])
return false
})
)
}
}
Protect Routes
Add the guard to your routes:
import { Routes } from '@angular/router'
import { AuthGuard } from './guards/auth.guard'
export const routes: Routes = [
{
path: 'login',
component: LoginComponent
},
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [AuthGuard]
},
{
path: 'profile',
component: ProfileComponent,
canActivate: [AuthGuard]
}
]
Display User Info
Show logged-in user information:
import { Component } from '@angular/core'
import { AuthService } from '../../services/auth.service'
import { Router } from '@angular/router'
@Component({
selector: 'app-navbar',
template: `
<nav *ngIf="authService.user$ | async as user">
<span>Welcome, {{ user.email }}</span>
<button (click)="logout()">Logout</button>
</nav>
`
})
export class NavbarComponent {
constructor(
public authService: AuthService,
private router: Router
) {}
async logout(): Promise<void> {
await this.authService.logout()
this.router.navigate(['/login'])
}
}
Best Practice Note
This is the same Firebase authentication pattern we use in CoreUI’s Angular admin templates. It provides secure, scalable authentication with minimal backend infrastructure.
For production applications, consider using CoreUI’s Angular Admin Template which includes pre-built Firebase integration, authentication flows, and protected routes. The template also provides UI components like Modal for authentication dialogs and Toast for auth feedback.
Related Articles
If you’re implementing authentication, you might also want to learn how to fetch data in Angular with HttpClient to connect authenticated users to your API endpoints.



