Angular 13 Firebase 7 Authentication Example Tutorial

This tutorial walks you through on how to create a complete Angular Firebase Authentication system from scratch.

We will implement and use the Firebase auth platform in Angular application to build a robust Login and Signup system.

Our user authentication application covers the following functionalities:

  • Sign-in with Google
  • Sign-in with username/password
  • Register with username/password
  • Email verification
  • Forgot password
  • Guard Routes with canActivate
  • Prevent user to access sign in and sign up URL when a user is already logged in
  • Handle logged-in user state with Local Storage

Create Angular Authentication Project

Install Angular CLI in your development system.

npm install -g @angular/cli

Execute command to install a fresh Angular application.

ng new angular-firebase-authentication

Move to the project root:

cd angular-firebase-authentication

Disable Strict Angular TypeStrict Errors

The latest version of Angular comes with strict mode, you have to manually disable the strict mode you can set “strict”: false, "noImplicitReturns": false and "strictTemplates": false inside the compilerOptions and angularCompilerOptions in tsconfig.json file.

Install Bootstrap package in Angular.

npm install bootstrap

Add bootstrap CSS in angular.json.

"styles": [
            "node_modules/bootstrap/dist/css/bootstrap.min.css",
            "src/styles.css"
          ]

Add Firebase in Angular

Adding Firebase in Angular is easy, it can be done with a single command. However, you must create a Firebase project for making the interaction between server and client.

npm install firebase @angular/fire

Open environment.ts file, add your firebase credentials inside the file.

export const environment = {
  production: false,
  firebaseConfig: {
    apiKey: "xxxxxxxxxxxxxx",
    authDomain: "xxxxxxxxxxxxxxxxxxxx",
    databaseURL: "xxxxxxxxxxxxxxxxxxxxx",
    projectId: "xxxxxxx",
    storageBucket: "xxxxxxx",
    messagingSenderId: "xxxxxx",
    appId: "xxxxx",
    measurementId: "xxxxxxxxxxxxxx"
  }
};

AngularFire is a Firebase package and has been installed, now add the given below code in app.module.ts.

import { AngularFireModule } from '@angular/fire/compat';
import { AngularFireAuthModule } from '@angular/fire/compat/auth';
import { AngularFirestoreModule } from '@angular/fire/compat/firestore';
import { environment } from '../environments/environment';


@NgModule({
  imports: [
    AngularFireModule.initializeApp(environment.firebaseConfig),
    AngularFireAuthModule,
    AngularFirestoreModule,
  ]
})

Create Angular Components

Generate following components to deal with User Registration, Signin, Forget Password and Email Verification:

ng g c components/dashboard
ng g c components/sign-in
ng g c components/sign-up
ng g c components/forgot-password
ng g c components/verify-email

Add Routing

Next, we create routes for angular authentication app in app-routing.module.ts file.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { SignInComponent } from './components/sign-in/sign-in.component';
import { SignUpComponent } from './components/sign-up/sign-up.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { ForgotPasswordComponent } from './components/forgot-password/forgot-password.component';
import { VerifyEmailComponent } from './components/verify-email/verify-email.component';

const routes: Routes = [
  { path: '', redirectTo: '/sign-in', pathMatch: 'full' },
  { path: 'sign-in', component: SignInComponent },
  { path: 'sign-up', component: SignUpComponent },
  { path: 'dashboard', component: DashboardComponent },
  { path: 'forgot-password', component: ForgotPasswordComponent },
  { path: 'email-verification', component: VerifyEmailComponent }
];

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

export class AppRoutingModule { }

Thereafter, add router-outlet in app.component.html file.

<router-outlet></router-outlet>

Create Authentication Service

To create Angular Authentication System we need to create central service with Firebase API.

Place following code in ng-auth.service.ts file.

import { Injectable, NgZone } from '@angular/core';
import * as auth from 'firebase/auth';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import {
  AngularFirestore,
  AngularFirestoreDocument,
} from '@angular/fire/compat/firestore';
import { Router } from '@angular/router';

export interface User {
  uid: string;
  email: string;
  displayName: string;
  photoURL: string;
  emailVerified: boolean;
}

@Injectable({
  providedIn: 'root',
})
export class NgAuthService {
  userState: any;

  constructor(
    public afs: AngularFirestore,
    public afAuth: AngularFireAuth,
    public router: Router,
    public ngZone: NgZone
  ) {
    this.afAuth.authState.subscribe((user) => {
      if (user) {
        this.userState = user;
        localStorage.setItem('user', JSON.stringify(this.userState));
        JSON.parse(localStorage.getItem('user'));
      } else {
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      }
    });
  }

  SignIn(email, password) {
    return this.afAuth
      .signInWithEmailAndPassword(email, password)
      .then((result) => {
        this.ngZone.run(() => {
          this.router.navigate(['dashboard']);
        });
        this.SetUserData(result.user);
      })
      .catch((error) => {
        window.alert(error.message);
      });
  }

  SignUp(email, password) {
    return this.afAuth
      .createUserWithEmailAndPassword(email, password)
      .then((result) => {
        this.SendVerificationMail();
        this.SetUserData(result.user);
      })
      .catch((error) => {
        window.alert(error.message);
      });
  }

  SendVerificationMail() {
    return this.afAuth.currentUser
      .then((u) => u.sendEmailVerification())
      .then(() => {
        this.router.navigate(['email-verification']);
      });
  }

  ForgotPassword(passwordResetEmail) {
    return this.afAuth
      .sendPasswordResetEmail(passwordResetEmail)
      .then(() => {
        window.alert('Password reset email sent, check your inbox.');
      })
      .catch((error) => {
        window.alert(error);
      });
  }

  get isLoggedIn(): boolean {
    const user = JSON.parse(localStorage.getItem('user'));
    return user !== null && user.emailVerified !== false ? true : false;
  }

  GoogleAuth() {
    return this.AuthLogin(new auth.GoogleAuthProvider());
  }

  AuthLogin(provider) {
    return this.afAuth
      .signInWithPopup(provider)
      .then((result) => {
        this.ngZone.run(() => {
          this.router.navigate(['dashboard']);
        });
        this.SetUserData(result.user);
      })
      .catch((error) => {
        window.alert(error);
      });
  }

  SetUserData(user) {
    const userRef: AngularFirestoreDocument<any> = this.afs.doc(
      `users/${user.uid}`
    );
    const userState: User = {
      uid: user.uid,
      email: user.email,
      displayName: user.displayName,
      photoURL: user.photoURL,
      emailVerified: user.emailVerified,
    };
    return userRef.set(userState, {
      merge: true,
    });
  }

  SignOut() {
    return this.afAuth.signOut().then(() => {
      localStorage.removeItem('user');
      this.router.navigate(['sign-in']);
    });
  }
}
  • User model contains the data that needs to be communicated with the server.
  • Import all the Firebase auth services and inject them in the constructor.
  • Define a variable userState which sustain the user authentication state.

Build Angular Login with Firebase

Use Angular NgAuthService service to create:

  • Firebase login with username and password
  • Firebase login with Gmail
  • Firebase Sign in with Facebook

Add code in sign-in.component.ts file.

import { Component, OnInit } from '@angular/core';
import { NgAuthService } from "../../ng-auth.service";

@Component({
  selector: 'app-sign-in',
  templateUrl: './sign-in.component.html',
  styleUrls: ['./sign-in.component.css']
})

export class SignInComponent implements OnInit {

  constructor(
    public ngAuthService: NgAuthService
  ) { }

  ngOnInit() { }

}

Place code in sign-in.component.html.

<div class="displayTable">
  <div class="displayTableCell">

    <div class="authBlock">
      <h3>Signin</h3>
      <div class="formGroup">
        <input type="text" class="form-control" placeholder="Username" #userName required>
      </div>

      <div class="formGroup">
        <input type="password" class="form-control" placeholder="Password" #userPassword required>
      </div>

      <div class="formGroup">
        <input type="button" class="btn btn-primary btn-block" value="Sign in"
          (click)="ngAuthService.SignIn(userName.value, userPassword.value)">
      </div>

      <div class="formGroup">
        <button type="button" class="btn btn-danger btn-block" (click)="ngAuthService.GoogleAuth()">
          Log in with Google
        </button>
      </div>

      <div class="forgotPassword">
        <span routerLink="/forgot-password">Forgot Password?</span>
      </div>
    </div>

    <div class="redirectToLogin">
      <span>Not registered yet?<span class="redirect" routerLink="/sign-up"> Register</span></span>
    </div>

  </div>
</div>

Build Firebase User Registration

Add code in sign-up.component.ts to create user registration with Firebase.

import { Component, OnInit } from '@angular/core';
import { NgAuthService } from "../../ng-auth.service";

@Component({
  selector: 'app-sign-up',
  templateUrl: './sign-up.component.html',
  styleUrls: ['./sign-up.component.css']
})

export class SignUpComponent implements OnInit {

  constructor(public ngAuthService: NgAuthService) { }

  ngOnInit(): void {
  }

}

Place code in sign-up.component.html.

<div class="displayTable">
  <div class="displayTableCell">

    <div class="authBlock">
      <h3>Register User</h3>

      <div class="formGroup">
        <input type="email" class="form-control" placeholder="Email Address" #userEmail required>
      </div>

      <div class="formGroup">
        <input type="password" class="form-control" placeholder="Password" #userPwd required>
      </div>

      <div class="formGroup">
        <input type="button" class="btn btn-block btn-primary" value="Sign Up"
          (click)="ngAuthService.SignUp(userEmail.value, userPwd.value)">
      </div>

      <div class="formGroup">
        <button type="button" class="btn btn-block btn-danger" (click)="ngAuthService.GoogleAuth()">
          Continue with Google
        </button>
      </div>
    </div>

    <div class="redirectToLogin">
      <span>Already have an account? <span class="redirect" routerLink="/sign-in">Log In</span></span>
    </div>
  </div>

</div>

Build Forgot Password in Angular Firebase

Place code in forgot-password.component.ts to create Forgot Password in Angular Firebase.

import { Component, OnInit } from '@angular/core';
import { NgAuthService } from "../../ng-auth.service";

@Component({
  selector: 'app-forgot-password',
  templateUrl: './forgot-password.component.html',
  styleUrls: ['./forgot-password.component.css']
})
export class ForgotPasswordComponent implements OnInit {

  constructor(public ngAuthService: NgAuthService) { }

  ngOnInit(): void {
  }

}

Paste code in forgot-password.component.html.

<div class="displayTable">
  <div class="displayTableCell">

    <div class="authBlock">
      <h3>Forgot Password</h3>

      <div class="formGroup">
        <input type="email" class="form-control" placeholder="Email Address" #passwordResetEmail required>
      </div>

      <div class="formGroup">
        <input type="submit" class="btn btn-primary btn-block" value="Reset Password"
          (click)="ngAuthService.ForgotPassword(passwordResetEmail.value)">
      </div>
    </div>

  </div>
</div>

Send Verification Email

Incorporate code in verify-email.component.ts to build sending verification email to newly registered user with Firebase and Angular.

import { Component, OnInit } from '@angular/core';
import { NgAuthService } from "../../ng-auth.service";

@Component({
  selector: 'app-verify-email',
  templateUrl: './verify-email.component.html',
  styleUrls: ['./verify-email.component.css']
})

export class VerifyEmailComponent implements OnInit {

  constructor(public ngAuthService: NgAuthService) { }

  ngOnInit(): void {
  }

}

Add code inside verify-email.component.html.

<div class="displayTable">
  <div class="displayTableCell">

    <div class="authBlock">
      <h3>Thank You for Signing up</h3>

      <div class="formGroup" *ngIf="ngAuthService.userState as user">
        <p class="text-center">Confirmation mail has been sent to <strong>{{user.email}}</strong>.</p>
      </div>

      <div class="formGroup">
        <button type="button" class="btn btn-block btn-success" (click)="ngAuthService.SendVerificationMail()">
          Resend Verification Email
        </button>
      </div>
    </div>


  </div>
</div>

Protect Routes with Angular 13 Route Guard

To secure routes in Angular, we need to use the CanActivate interface.

Interface that a class can implement to be a guard deciding if a route can be activated. If all guards return true, navigation continues. If any guard returns false, navigation is cancelled.

Create route guard service with following command.

ng generate guard auth

Add code in auth.guard.ts.

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { NgAuthService } from "./ng-auth.service";

@Injectable({
  providedIn: 'root'
})

export class AuthGuard implements CanActivate {

  constructor(
    public ngAuthService: NgAuthService,
    public router: Router
  ){ }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
      if(this.ngAuthService.isLoggedIn !== true) {
        this.router.navigate(['sign-in'])
      }
      return true;
  }
  
}

Register route guard with component, add code in app-routing.module.ts.

import { AuthGuard } from "./auth.guard";

const routes: Routes = [
  { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
];

Store User State with Local Storage

In this step we will learn to keep Logged-in user state with localStorage object in Angular.

Add code in ng-auth.service.ts.

import { Injectable, NgZone } from '@angular/core';
import * as auth from 'firebase/auth';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import {
  AngularFirestore,
  AngularFirestoreDocument,
} from '@angular/fire/compat/firestore';
import { Router } from '@angular/router';

export interface User {
  uid: string;
  email: string;
  displayName: string;
  photoURL: string;
  emailVerified: boolean;
}

@Injectable({
  providedIn: 'root',
})

export class NgAuthService {
  userState: any;

  constructor(
    public afs: AngularFirestore,
    public afAuth: AngularFireAuth,
    public router: Router,
    public ngZone: NgZone
  ) {
    this.afAuth.authState.subscribe((user) => {
      if (user) {
        this.userState = user;
        localStorage.setItem('user', JSON.stringify(this.userState));
        JSON.parse(localStorage.getItem('user'));
      } else {
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      }
    });
  }

  SignIn(email, password) {
    return this.afAuth
      .signInWithEmailAndPassword(email, password)
      .then((result) => {
        this.ngZone.run(() => {
          this.router.navigate(['dashboard']);
        });
        this.SetUserData(result.user);
      })
      .catch((error) => {
        window.alert(error.message);
      });
  }

  SignUp(email, password) {
    return this.afAuth
      .createUserWithEmailAndPassword(email, password)
      .then((result) => {
        this.SendVerificationMail();
        this.SetUserData(result.user);
      })
      .catch((error) => {
        window.alert(error.message);
      });
  }

  SendVerificationMail() {
    return this.afAuth.currentUser
      .then((u) => u.sendEmailVerification())
      .then(() => {
        this.router.navigate(['email-verification']);
      });
  }

  ForgotPassword(passwordResetEmail) {
    return this.afAuth
      .sendPasswordResetEmail(passwordResetEmail)
      .then(() => {
        window.alert('Password reset email sent, check your inbox.');
      })
      .catch((error) => {
        window.alert(error);
      });
  }

  get isLoggedIn(): boolean {
    const user = JSON.parse(localStorage.getItem('user'));
    return user !== null && user.emailVerified !== false ? true : false;
  }

  GoogleAuth() {
    return this.AuthLogin(new auth.GoogleAuthProvider());
  }

  AuthLogin(provider) {
    return this.afAuth
      .signInWithPopup(provider)
      .then((result) => {
        this.ngZone.run(() => {
          this.router.navigate(['dashboard']);
        });
        this.SetUserData(result.user);
      })
      .catch((error) => {
        window.alert(error);
      });
  }

  SetUserData(user) {
    const userRef: AngularFirestoreDocument<any> = this.afs.doc(
      `users/${user.uid}`
    );
    const userState: User = {
      uid: user.uid,
      email: user.email,
      displayName: user.displayName,
      photoURL: user.photoURL,
      emailVerified: user.emailVerified,
    };
    return userRef.set(userState, {
      merge: true,
    });
  }

  SignOut() {
    return this.afAuth.signOut().then(() => {
      localStorage.removeItem('user');
      this.router.navigate(['sign-in']);
    });
  }
}

Place code in dashboard.component.html.

 <div class="container mt-5" style="max-width: 600px">

   <div class="row" *ngIf="ngAuthService.userState as user">
     <div class="media">
       <img class="align-self-start mr-5 img-thumbnail rounded-circle"
         src="{{(user.photoURL) ? user.photoURL : '/assets/dummy.jpg'}}" alt="{{user.displayName}}">
       <div class="media-body">
         <h2>Hi: <strong>{{(user.displayName) ? user.displayName : 'User'}}</strong></h2>
         <p>User ID: <strong>{{user.uid}}</strong></p>
         <p>Email: <strong>{{user.email}}</strong></p>
       </div>
     </div>
   </div>

   <a class="btn btn-block btn-primary" (click)="ngAuthService.SignOut()">
     Sign Out
   </a>

 </div>

Now, open dashboard.component.ts file, import and inject the NgAuthService.

import { Component, OnInit } from '@angular/core';
import { NgAuthService } from '../../ng-auth.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css'],
})

export class DashboardComponent implements OnInit {
  constructor(public ngAuthService: NgAuthService) {}

  ngOnInit(): void {}
}

To style the firebase auth app, add the given css in src/styles.css file.

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  font-weight: 400;
  width: 100%;
  height: 100%;
}

.feather {
  width: 16px;
  height: 16px;
  vertical-align: text-bottom;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-weight: 600;
}

.media-body h1 {
  font-weight: 300;
  margin-bottom: 20px;
}

.media-body h1 strong {
  font-weight: 600;
}

.media-body p {
  margin-bottom: 10px;
  font-weight: 300;
}

.media-body p strong {
  margin-bottom: 10px;
  font-weight: 600;
}

.px-logo {
  display: block;
  clear: both;
  margin: 0 auto 20px;
  width: 220px;
}

.px-logo a img {
  width: 100%;
}

.displayTable {
  display: table;
  width: 100%;
  height: 100%;
  background: #fc466b; /* fallback for old browsers */
  background: -webkit-linear-gradient(
    to right,
    #3f5efb,
    #fc466b
  ); /* Chrome 10-25, Safari 5.1-6 */
  background: linear-gradient(
    to right,
    #3f5efb,
    #fc466b
  ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}

.displayTableCell {
  display: table-cell;
  vertical-align: middle;
  width: 100%;
  height: 100%;
}

h3 {
  text-align: center;
  font-size: 22px;
  margin: 0 0 20px;
}

.authBlock {
  margin: 0 auto;
  max-width: 400px;
  background: white;
  padding: 30px 40px 10px;
  overflow: hidden;
  -webkit-box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.04);
  box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.04);
}

.formGroup {
  margin-bottom: 20px;
  float: left;
  width: 100%;
}

.halfWidth {
  width: 48.5%;
}

.left {
  float: left;
}

.right {
  float: right;
}

.forgotPassword {
  text-align: center;
  margin: -12px 0 15px 0;
  float: left;
  width: 100%;
}

.forgotPassword span {
  color: #3c89ef;
  font-size: 14px;
  font-weight: 400;
  cursor: pointer;
  display: inline-block;
  padding-top: 20px;
}

.redirectToLogin {
  padding: 15px 0 0;
  text-align: center;
  font-size: 14px;
  font-weight: 400;
  display: block;
  color: rgba(255, 255, 255, 0.6);
}

.redirectToLogin .redirect {
  cursor: pointer;
  color: #ffffff;
  text-decoration: underline;
}

/* * Sidebar */
.sidebar {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 100;
  /* Behind the navbar */
  padding: 48px 0 0;
  /* Height of navbar */
  box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.1);
}

.sidebar-sticky {
  position: relative;
  top: 0;
  height: calc(100vh - 48px);
  padding-top: 0.5rem;
  overflow-x: hidden;
  overflow-y: auto;
}

@supports ((position: -webkit-sticky) or (position: sticky)) {
  .sidebar-sticky {
    position: -webkit-sticky;
    position: sticky;
  }
}

.sidebar .nav-link {
  font-weight: 500;
  color: #333;
}

.sidebar .nav-link .feather {
  margin-right: 4px;
  color: #999;
}

.sidebar-heading {
  font-size: 0.75rem;
  text-transform: uppercase;
}

.nav-link {
  padding: 1.5rem 1rem;
  border-bottom: 1px solid #dde0e2;
  cursor: pointer;
}

.sidebar .nav-link.active,
.sidebar a:hover,
a:not([href]):not([tabindex]):focus,
a:not([href]):not([tabindex]):hover {
  color: #e91e63;
  background: #efefef;
}

/* * Content */
[role="main"] {
  padding-top: 48px;
}

.dasboard-text {
  border-left: 1px solid rgb(255, 255, 255, 0.3);
  color: rgb(255, 255, 255, 0.5);
  display: inline-block;
  padding: 0 0 0 14px;
  font-size: 15px;
  margin-left: 15px;
  position: relative;
  top: -1px;
}

/* * Navbar */
.navbar-brand {
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

.navbar .form-control {
  padding: 0.75rem 1rem;
  border-width: 0;
  border-radius: 0;
}

.form-control-dark {
  color: #fff;
  background-color: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.1);
}

.form-control-dark:focus {
  border-color: transparent;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25);
}

.form-control:focus {
  border-color: #00bcd4;
  box-shadow: none;
}

.form-control {
  font-size: 14px;
}

.bg-dark {
  background-color: #3f51b5 !important;
}

.gap-right {
  margin-right: 10px;
}

i {
  width: 22px;
  text-align: center;
  margin-right: 5px;
}

.inner-adjust {
  padding: 0 20px;
}

.action-block {
  cursor: pointer;
}

.action-block .fa-edit:hover {
  color: #009688;
}

.action-block .fa-trash-alt:hover {
  color: #e91e63;
}

.btn-primary.focus,
.btn-primary:focus {
  box-shadow: none;
}

/* Pagination */
body pagination-template {
  padding: 0;
  margin: 8px 0 0;
  float: left;
  width: 100%;
  text-align: right;
}

body .ngx-pagination li:last-child {
  margin: 0;
}

body .ngx-pagination .current {
  background: #055af9;
}

.ngx-pagination a:hover,
.ngx-pagination button:hover {
  text-decoration: none;
}

/* Error */
.error {
  color: red;
  margin-top: 5px;
}

input.ng-invalid.ng-touched {
  border: 1px solid red;
}

.btn-success.disabled,
.btn-success:disabled {
  cursor: not-allowed;
}

/* Nav */
body .navbar {
  padding: 6px 0 !important;
}

body .navbar-brand {
  background: none;
}

.brand-logo {
  max-width: 85%;
}

.pt-3,
.py-3 {
  padding-top: 2.4rem !important;
}

.sidebar-sticky {
  padding-top: 1.2rem !important;
}

/* Form */
label {
  font-weight: 500;
}

.form-control {
  padding: 1.375rem 0.75rem;
}

/* Misc */
.no-data img {
  max-width: 420px;
  margin: 20px auto 0;
}

.nodata-msg {
  margin: 25px 0 15px;
  font-size: 28px;
  color: #a9a6c5;
  font-weight: 300;
  letter-spacing: 0.2px;
}

[role="main"] {
  padding-top: 65px;
}

.preloader {
  min-height: 400px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: -15px;
}

.custom-text {
  font-size: 15px;
  color: #5f5f5f;
  letter-spacing: 0.2px;
}

.navbar-dark .navbar-brand {
  margin-left: 6px;
}

.custom-text strong {
  color: #3a3a3a;
}

.mb-3,
.my-3 {
  margin-bottom: 1.4rem !important;
}

.user-image {
  width: 42px;
  height: 42px;
  display: inline-block;
  border-radius: 50%;
  vertical-align: middle;
  margin-right: 7px;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: 0 0;
}

body .table thead th {
  background: #f3f5ff;
}

.userImage {
  max-width: 125px;
}

.rounded-circle {
  max-width: 150px;
}

To start the application execute ng serve --open command.

Angular 13 Firebase 7 Authentication Example Tutorial

You can download the full code of this example app from GitHub.