How to Add Firebase Authentication in Ionic 7 Angular

Last Updated on by in Firebase

A thorough step by step Ionic Firebase Authentication tutorial, we are going to learn how to add authentication in an Ionic app using Firebase (AngularFire – official library for Firebase and Angular) package from scratch.User authentication is an essential feature in almost every web or mobile application. It secures your relevant data, allows access to authorized users and empowers the development of personalized user experience.

If you are a backend developer, then you must be aware, it requires lots of time and efforts to create a secure user authentication system.

Let’s get started and start learning how to Add Firebase Authentication in Ionic App.

Setting up Firebase Project

To set up an account, go to console.firebase.google.com and then follow the given below methods to create Firebase account.

Setting up Firebase Project

Create a Firebase account, then create a project in Firebase dashboard. Just click on Add project button and create a new authentication project in Firebase.

Enter the project name in the project name filed then click on the large “Continue” button.

Ionic Firebase Auth Tutorial

Once your project is created, then you will be redirected to the Firebase dashboard. It will ask you to add Firebase to your Ionic app, click on the marked red icon.

Ionic Dashboard

Next, Enter the app’s nickname and then click on the next button.

Ionic Firebase App Nickname

You will see Firebase database configuration code, copy this code we need to add this configuration code in an Ionic Angular app.

Firebase Config Keys

We are using the Realtime Database in this project so select the option, click on the “create database” button.

Firebase Realtime Database

Next, set the database rules to “start in test mode”. Do not use test mode rule for real world app.

Ionic Firebase Security

Click on the left side Authentication menu item, and it will take you to the Authentication page. It allows you to add user manually, manage users from different providers without setting up a server-side environment.

Configure Firebase Sign-in Providers

We are going to enable configure Firebase Sign-in providers in the Firebase database. We will enable Email/Password, Login with Google, however, you can enable any provider from the given options based on your authentication system requirements.

configure Firebase Sign-in providers

Firebase offers you to create custom Templates for Email address verification, Password reset, Email address change, SMPT settings, and SMS verification.

create Firebase custom templates

I wrote a step by step article to Set up Firebase Database in an Ionic App

Configure Firebase in Ionic

First, Install the Ionic CLI.

sudo npm install -g ionic

Run the given below command to create a brand new Ionic project:

ionic start ionic-firebase-authentication blank --type=angular

We are using the Ionic sidemenu project for Ionic Firebase authentication example.

Get inside the project folder:

cd ionic-firebase-authentication

Run the below command to add the native core package.

npm install @ionic-native/core --legacy-peer-deps

Disable Strict Type Errors

To get rid from strict type warnings or errors ensure that you set “strictTemplates”: false under angularCompilerOptions in tsconfig.json file.

Setting up AngularFire in Ionic Project

Install the AngularFire library (official Firebase package) to connect Ionic/Angular app with Firebase.

Run the following command in the terminal.

sudo npm install @angular/fire firebase@9.16.0 --legacy-peer-deps

Add Firebase config details in the src/environment.ts file.

export const environment = {
  production: false,
  firebaseConfig: {
    apiKey: "xxxxxxxx-xxxxxxxx",
    authDomain: "xxxxxxxxxxxxxxxxxxxxxxxx",
    databaseURL: "xxxxxxxxxxxxxxxxxxxxxxxx",
    projectId: "xxxxxxxx",
    storageBucket: "xxxxxxxx",
    messagingSenderId: "xxxxxx",
    appId: "xxxxx",
    measurementId: "xxxxxxxxxxxxxxxx"
  }
};

Furthermore, you have to add firebase services in app.module.ts File.

// Firebase services + environment module
import { AngularFireModule } from '@angular/fire/compat';
import { AngularFireAuthModule } from '@angular/fire/compat/auth';
import { AngularFireStorageModule } from '@angular/fire/compat/storage';
import { AngularFirestoreModule } from '@angular/fire/compat/firestore';
import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
import { environment } from '../environments/environment';


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

Create Authentication Service in Ionic with Firebase

Create a Firebase authentication service that we are going to use in our Ionic app.

Create a shared folder, create auth.ts file in it, we define the data types for the user object. Add the following code in the shared/user.ts file:

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

Create the shared/authentication-service.ts file, add the below following code in the file.

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

@Injectable({
  providedIn: 'root',
})
export class AuthenticationService {
  userData: any;

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

  // Login in with email/password
  SignIn(email: any, password: any) {
    return this.ngFireAuth.signInWithEmailAndPassword(email, password);
  }

  // Register user with email/password
  RegisterUser(email: any, password: any) {
    return this.ngFireAuth.createUserWithEmailAndPassword(email, password);
  }

  // Email verification when new user register
  SendVerificationMail() {
    return this.ngFireAuth.currentUser.then((user: any) => {
      return user.sendEmailVerification().then(() => {
        this.router.navigate(['login']);
      });
    });
  }

  // Recover password
  PasswordRecover(passwordResetEmail: any) {
    return this.ngFireAuth
      .sendPasswordResetEmail(passwordResetEmail)
      .then(() => {
        window.alert(
          'Password reset email has been sent, please check your inbox.'
        );
      })
      .catch((error) => {
        window.alert(error);
      });
  }

  // Returns true when user is looged in
  get isLoggedIn(): boolean {
    const user = JSON.parse(localStorage.getItem('user') || '{}');
    return user !== null && user.emailVerified !== false ? true : false;
  }

  // Returns true when user's email is verified
  get isEmailVerified(): boolean {
    const user = JSON.parse(localStorage.getItem('user') || '{}');
    return user.emailVerified !== false ? true : false;
  }

  // Sign in with Gmail
  GoogleAuth() {
    return this.AuthLogin(new auth.GoogleAuthProvider());
  }

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

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

  // Sign-out
  SignOut() {
    return this.ngFireAuth.signOut().then(() => {
      localStorage.removeItem('user');
      this.router.navigate(['login']);
    });
  }
}

We imported the AngularFireAuth service and injected it into the constructor, then subscribed this method.

It returns the user object from the Firebase database. We are saving the user object in the localStorage to maintain the logged-in user state.

In the above service file, we created the following methods using Firebase API for the following functionalities register with username/password, login with username/password, recover password, email verification, route protection.

Create User Registration in Ionic

Let’s create user registration functionality in Ionic app using Firebase API, in the previous step, we created a service that we are going to use in this step.

First, create a registration component using the command below:

ng generate page registration

Open the app/registration.page.ts file and add the given below code in it.

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthenticationService } from '../shared/authentication-service';

@Component({
  selector: 'app-registration',
  templateUrl: './registration.page.html',
  styleUrls: ['./registration.page.scss'],
})

export class RegistrationPage implements OnInit {
  constructor(
    public authService: AuthenticationService,
    public router: Router
  ) {}

  ngOnInit() {}

  signUp(email: any, password: any) {
    this.authService
      .RegisterUser(email.value, password.value)
      .then((res) => {
        // Do something here
      })
      .catch((error) => {
        window.alert(error.message);
      });
  }
}

We need to import the AuthenticationService and Router service at the top of the registration.page.ts file.

Inject AuthenticationService and Router service in the constructor.

Then, define the signUp(email, password) method and pass email and password values in it. Inside this function call authService.RegisterUser(x, y) the method, it returns the Promise, in a while, we will be defining the user email verification method inside then block.

Click here for creating service in Angular application.

Open the registration.page.html file to create the user registration form in Ionic app.

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button>
    </ion-buttons>
    <ion-title>Register User</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <form>    
    <ion-item lines="full">
      <ion-label position="floating">Email</ion-label>
      <ion-input type="text" #email required></ion-input>
    </ion-item> 

    <ion-item lines="full">
      <ion-label position="floating">Password</ion-label>
      <ion-input type="password" #password required></ion-input>
    </ion-item>

    <ion-row>
      <ion-col> 
      <ion-button type="submit" (click)="signUp(email, password)" expand="block">Register</ion-button>
      </ion-col>
    </ion-row>
  </form>
</ion-content>

Create user form with email and password field to register the user, in the ion-button directive, we declared the signUp() method and passing the email/password value in it.

If you are a beginner, then do check out how to create and validate a form in Ionic.

User Registration with Email Verification

Now, we are going to verify the email id by sending a verification email on the registered email address using Firebase sendEmailVerification() method.

We need to generate the component, and a user will be redirected to this component when successfully registered.

ng generate page verify-email

Go to verify-email.page.ts file, import and inject AuthenticationService inside the verify-email component.

import { Component, OnInit } from '@angular/core';
import { AuthenticationService } from "../shared/authentication-service";

@Component({
  selector: 'app-verify-email',
  templateUrl: './verify-email.page.html',
  styleUrls: ['./verify-email.page.scss'],
})
export class VerifyEmailPage implements OnInit {

  constructor(
    public authService: AuthenticationService
  ) { }

  ngOnInit() {
  }

}

Add the following code in the verify-email.page.html file.

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button>
    </ion-buttons>
    <ion-title>verify-email</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-grid>
    <ion-row>
      <h2>Ionic Firebase Verify Email</h2>
      <p>
        Please check your email and click on the link to verfiy your email address.
      </p>
      <ion-button type="submit" (click)="authService.SendVerificationMail()" expand="block">
        Resend Verification Email
      </ion-button>
    </ion-row>
  </ion-grid>
</ion-content>

We need to call the SendVerificationMail() method in the signUp() method’s Promise section. Go to registration.page.ts, replace the current signUp() method with the following code.

signUp(email, password){
      this.authService.RegisterUser(email.value, password.value)
      .then((res) => {
        // Do something here
        this.authService.SendVerificationMail()
        this.router.navigate(['verify-email']);
      }).catch((error) => {
        window.alert(error.message)
      })
  }

In the main service file, we declared the given below code, and this is responsible for email verification when a new user registers.

  SendVerificationMail() {
    return this.ngFireAuth.auth.currentUser.sendEmailVerification()
    .then(() => {
      this.router.navigate(['verify-email']);
    })
  }

Login with Email and Password

In this step, we need to add a login page in an Ionic app. This step will allow users to login with email and password for already registered user.

Run the following command to generate a login component:

ng generate page login

Go to login.page.ts file and add the following code inside of it.

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthenticationService } from '../shared/authentication-service';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {
  constructor(
    public authService: AuthenticationService,
    public router: Router
  ) {}

  ngOnInit() {}

  logIn(email: any, password: any) {
    this.authService
      .SignIn(email.value, password.value)
      .then((): any => {
        if (this.authService.isEmailVerified) {
          this.router.navigate(['dashboard']);
        } else {
          window.alert('Email is not verified');
          return false;
        }
      })
      .catch((error) => {
        window.alert(error.message);
      });
  }
}

The SignIn() method works the same way as the register method does the only difference is we are using signInWithEmailAndPassword() method instead of createUserWithEmailAndPassword() method.

The isEmailVerified() method returns true when a user email has been verified.

Open login.page.html file and place the following code.

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button>
    </ion-buttons>
    <ion-title>Sign in User</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <form>    
    <ion-item lines="full">
      <ion-label position="floating">Email</ion-label>
      <ion-input type="text" #email required></ion-input>
    </ion-item> 

    <ion-item lines="full">
      <ion-label position="floating">Password</ion-label>
      <ion-input type="password" #password required></ion-input>
    </ion-item>

    <ion-row>
      <ion-col> 
      <ion-button type="submit" (click)="logIn(email, password)" expand="block">Login</ion-button>
      </ion-col>
    </ion-row>
  </form>
</ion-content>

Firebase Sign-in Providers – Login with Gmail

If you want to save your users time and don not, want to mesmerize with username/password combination. Then, we have got a solution for you to login with social sign-in providers.

This saves users time, and a user doesn’t have to verify the email and get into the password reset process. It comes in handy in a mobile app, and Google login works automatically with a pre-installed Google app.

Google Login has various advantages such as easy to use, and no forgotten password, no email verification, and google trust.

So far, we have learnt to work with Firebase ready-made email authentication, but in this step, we are going to learn how to authenticate using social logins.

Firebase offers social login with Facebook, GitHub, Microsoft, Google, Twitter, Apple, Yahoo, Game Center (Beta), Phone number, and Anonymous.

We are going to focus on Login with Google In this tutorial. For the rest of the other social-providers, we will create tutorials soon.

We need to import the AuthenticationService in the Ionic page, though we have already imported and injected the AuthenticationService in login template.

Next, we just have to create a button and access the GoogleAuth() method via the auth service API.

Here is the final code in login.page.html file.

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button>
    </ion-buttons>
    <ion-title>Sign in User</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <form>
    <ion-item lines="full">
      <ion-label position="floating">Email</ion-label>
      <ion-input type="text" #email required></ion-input>
    </ion-item>

    <ion-item lines="full">
      <ion-label position="floating">Password</ion-label>
      <ion-input type="password" #password required></ion-input>
    </ion-item>

    <ion-row>
      <ion-col>
        <ion-button
          type="submit"
          (click)="logIn(email, password)"
          expand="block"
          >Login</ion-button
        >
      </ion-col>
    </ion-row>

    <span class="divider line one-line">or</span>

    <ion-row>
      <ion-col>
        <ion-button
          type="submit"
          color="danger"
          (click)="authService.GoogleAuth()"
          expand="block"
        >
          Login with Google
        </ion-button>
      </ion-col>
    </ion-row>
  </form>
</ion-content>

Once the user is logged in it will be redirected to the dashboard page.

Firebase User Logout

In this final step, we are going to add a secure method to Logout from the Ionic app using Firebase API.

Run the following command to generate dashboard component:

ng generate page dashboard

Go to dashboard.page.ts file, and place the following code.

import { Component, OnInit } from '@angular/core';
import { AuthenticationService } from "../shared/authentication-service";

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

export class DashboardPage implements OnInit {

  constructor(
    public authService: AuthenticationService
  ) { }

  ngOnInit() {
  }

}

Next, open the dashboard.page.html file and access the SignOut() method. This method makes the call to auth.signOut() method that helps in logging out the current user from the Firebase database. It also removes the current firebase user from the localStorage.

<ion-button type="submit" (click)="authService.SignOut()" expand="block">Logout</ion-button>

Head over to home.page.html file and add the given code into the file.

<ion-header>
  <ion-toolbar>
    <ion-title> Ionic 6 Firebase Authentication Example </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content class="auth-form">
  <ion-grid>
    <ion-row>
      <ion-col class="ion-align-self-center">
        <ion-button
          [routerLink]="['/registration']"
          expand="block"
          color="primary"
          >Register</ion-button
        >
        <span class="divider line one-line">or</span>
        <span class="already">Already a user?</span>
        <ion-button [routerLink]="['/login']" expand="block" color="danger"
          >Sign In</ion-button
        >
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

Reset Password in Firebase

Execute command to generate password recover component in ionic.

ng generate page password-reset

Once, the pages are created, move on to login.page.html file and replace the existing code of the file with the following code.

We have added the Password Reset button with the associated route in the above file.

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button>
    </ion-buttons>
    <ion-title>Sign in User</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-item lines="full">
    <ion-label position="floating">Email</ion-label>
    <ion-input type="text" #email required></ion-input>
  </ion-item>

  <ion-item lines="full">
    <ion-label position="floating">Password</ion-label>
    <ion-input type="password" #password required></ion-input>
  </ion-item>

  <ion-row>
    <ion-col>
      <ion-button type="submit" (click)="logIn(email, password)" expand="block"
        >Login</ion-button
      >
    </ion-col>
  </ion-row>

  <ion-row>
    <ion-col>
      <ion-button
        expand="block"
        color="warning"
        [routerLink]="['/password-reset']"
      >
        Password Reset
      </ion-button>
    </ion-col>
  </ion-row>

  <ion-row>
    <ion-col>
      <ion-button
        type="submit"
        color="danger"
        (click)="authService.GoogleAuth()"
        expand="block"
      >
        Login with Google
      </ion-button>
    </ion-col>
  </ion-row>
</ion-content>

Next up, you need to insert the given code into the password-reset.page.ts file.

import { Component, OnInit } from '@angular/core';
import { AuthenticationService } from '../shared/authentication-service';

@Component({
  selector: 'app-password-reset',
  templateUrl: './password-reset.page.html',
  styleUrls: ['./password-reset.page.scss'],
})

export class PasswordResetPage implements OnInit {
  constructor(public authService: AuthenticationService) {}

  ngOnInit() {}

}

Eventually, you have to add the following code inside the password-reset.page.html file.

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button>
    </ion-buttons>
    <ion-title>Ionic Firebase Recover Passowrd Example</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-content>
    <ion-item lines="full">
      <p>Enter email to send password reset instructions.</p>
    </ion-item>

    <form>
      <ion-row>
        <ion-col>
          <ion-item lines="full">
            <ion-label position="floating">Email</ion-label>
            <ion-input type="text" #email required></ion-input>
          </ion-item>
        </ion-col>
      </ion-row>

      <ion-row>
        <ion-col>
          <ion-button
            type="submit"
            color="danger"
            (click)="authService.PasswordRecover(email.value)"
            expand="block"
          >
            Send Password Reset Mail
          </ion-button>
        </ion-col>
      </ion-row>
    </form>
  </ion-content>
</ion-content>

Finally, on your terminal type the given command and press enter to test the app:

ionic serve -l

Conclusion

Finally, we have completed Ionic Firebase Authentication tutorial with various authentication examples. This blog post helped us to learn how to implement Firebase authentication in Ionic and Angular app.

We have covered following topics in this tutorial:

  • Register with username and password
  • How to send verification email to register user?
  • How to login with Google in an Ionic app?
  • Login with username and password using Firebase API in Ionic
  • How to store user object in localStorage?
  • How to log out user from localStorage and Firebase database?

Happy Coding!