Edupala

Comprehensive Full Stack Development Tutorial: Learn Ionic, Angular, React, React Native, and Node.js with JavaScript

How to implement ionic firebase authentication

Ionic firebase authentication

We can easily integrate Firebase authentication in ionic. Ionic firebase authentication we can use third-party auth providers like Google, Twitter, Facebook, and more. These third-party service providers are the industry standards for token-based authentication and authorization for web, desktop, and mobile applications. These third-party service providers act as an intermediary on the behalf of the end-user allowing them to log in without exposing the user’s password.

In this tutorial, we’ll explore how to configure and implement Ionic firebase authentication using Google, and regular login with (Email and password). We’ll also learn how to email confirm and reset forgotten passwords.

Setting up an Ionic Firebase project

With the release of ionic version 4, the Ionic framework is no longer limited to angular. Ionic allows us to create ionic projects in different front-end frameworks like Angular, Vue, and React. Let’s first create a blank Ionic Angular project for our ionic Firestore example and add angularFire and firebase.

ionic start firebaseAuth blank --type=angular
npm install firebase @angular/fire –-save

The above command will create an ionic project and install a firebase and angular/fire library in our project. AngularFire is an official angular library to implement Firebase functionalities in the Angular project, as we are using the Ionic Angular project. In our application, some of the data are for public and some for private and we need authentication functionalities that allows user to save, edit, and delete their personal data. We’ll continue from our previous articles where we have already added data to our firebase project as this article is only focused on Ionic firebase authentication only. We have articles on the following.

  • Ionic firebase CRUD operation.
  • Ionic Firebase login with Facebook.
  • Ionic Firebase authentication Guard for authorization, allowing authenticate users or Admin to edit| delete their data.

Here is a screenshot of our Ionic firebase authentication

Ionic firebase authentication

Create and configure our poject in Firebase console

In this tutorial we are focusing only on Ionic firebase authentication, we have already covered how to configure and set up the firebase project in the Firebase console in detail. If you have not completed the firebase configuration, then check our previous articles. In this article, we are implementing the following Ionic Firebase authentication activities.

  1. Ionic firebase Google login.
  2. Ionic firebase signup and login with email and password.
  3. Ionic firebase email confirmation and password reset.

Before adding login/signup functionalities, we must activate Sign-in providers for Google, and email in Firebase. Hence, go to your project Firebase console, click on Authentication under in dashboard at the left site and we need to enable sign methods.

Ionic firebase authentication

Enable Gmail Sign-In in Firebase

Enabling Firebase Email/Password authentication is straightforward. In Firebase console and to enable Gmail authentication for our app. To enable Gmail authentication we need to go to  Firebase Console and locate the app you’re using. Inside the app’s dashboard, you’re going to go into Authentication > Sign-In Method > Gmail and click the Enable toggle to enable.

For most of the authentication in Ionic through a 3rd party is setting up the configuration and actually writing code in less and easier. We need to add a user model, let’s create folder models in the app folder and create a file user.ts file and add the following code.

export interface IUser {
    name: string;
    email: string;
    photoURL: string;
}

Create Authentication service for Login Activities

We need a service to handle authentication activities, it recommends an approach to use a service that hides direct access of data to the rest of the application. Service allows us to share our data across applications. We need to create a service that can be used to perform authentication and determine whether the application has been authenticated. Let’s run the following command to generate auth service.

ionic generate service services/auth

In src/app/services/auth.service.ts add the following code for Google authentication, signup, login with email and password, and password reset.

import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { ActivatedRoute, Router } from '@angular/router';
// import * as firebase from 'firebase';
import firebase from 'firebase/app';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { AngularFireAuth } from '@angular/fire/auth';
import { IUser } from '../models/user';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  appUser$: Observable<IUser>;

  constructor(
    public afAuth: AngularFireAuth,
    private route: ActivatedRoute,
    private router: Router,
    private db: AngularFirestore) {

    // Get the auth state, then fetch the Firestore user document or return null
    this.appUser$ = this.afAuth.authState.pipe(
      switchMap(user => {
        // If the user is logged in, return the user details.
        if (user) {
          return this.db.doc<IUser>(`appusers/${user.uid}`).valueChanges();
        } else {
          // If the user is NOT logged in, return null.
          return of(null);
        }
      })
    );
  }

  async googleLogin() {
    const credential = await this.afAuth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
    return this.updateUserData(credential.user);
  }


  signUpWithEmail(data: any) {
    this.afAuth.createUserWithEmailAndPassword(data.email, data.password)
     .then(data => {
      if (data.user.emailVerified) {
        this.router.navigate(['/']);
      } else {
        data.user.sendEmailVerification().then(() => {
          alert('Please verify your email');
          this.afAuth.signOut();
        })
      }
    });
  }

  loginWithEmail(data: any) {
    this.afAuth.signInWithEmailAndPassword(data.email, data.password)
    .then(data => {
      alert('Login successful');
      this.router.navigateByUrl('/');
    })

  }

  resetPassword(email: string) {
    this.afAuth.sendPasswordResetEmail(email).then(() => {
      alert('Please check your email, we have emailed you a password reset link');
    }).catch((error) => {
      if (error.code === 'auth/user-not-found') {
        alert('Sorry, user not found');
      }
    });
  }


  // Save the user data to firestore on Google|facebook login
  private updateUserData(user) {
    const userRef = this.db.doc(`usersProfile/${user.uid}`);
    const data = {
      name: user.displayName,
      email: user.email,
      photoURL: user.photoURL
    };
    return userRef.set(data, { merge: true });
  }
}

 
logout() {
    this.afAuth.signOut().then(() => {
      this.router.navigate(['/']);
    });
 }

We have used and injected AngularFire into our auth service constructor. Here we have added different methods in our auth service, these methods are easily understandable. We have users authenticate with Google, and Google OAuth API will return credential data like user name, email, and profile picture. We have saved all this credential data from Google in usersProfile collection. And some types of data are returned by the third-party OAuth like Facebook. For login with email and password, we have no data like user name, we need to create manually when the user signup for authentication by adding fields like a username. I have the reader figure out how to implement this logic which is easy and straightforward.

Build Login and sign page for Ionic firebase authentication

Now we have created auth service to implement our authentication logic, now we need consumers of our authentication logic. Let generate a signup and login page by running the following commands.

ionic generate page auth/login
ionic generate page auth/signup

All are authentication-related components and pages are kept in the src/app/auth folder, here we have two pages. Let first implement a signup page where we have a login form with two fields email and password and Signup button. Here is a screenshot of our signup page.

ionic firebase signup page

Let edit the app/auth/signup.page.ts file, import authService, and formBuilder.

import { Component } from '@angular/core';
import { NgForm } from '@angular/forms';
import { AuthService } from 'src/app/services/auth.service';

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

  signup = { email: '', password: '' };
  submitted = false;

  constructor(private authService: AuthService) { }

  onSignup(form: NgForm) {
    if (form.valid) {
      this.authService.signUpWithEmail({ email: form.control.value.email, password: form.control.value.password});
    }
  }
}

The above code is straightforward, we need to specify the user email and password for signup by calling authService.signUpWithEmail methods. Now let’s edit our signup template to add a template form with email and password as form fields.

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
    <ion-title>Signup</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <div class="signup-logo">
    <img src="assets/images/ionic-logo.png" alt="Ionic Logo">
  </div>

  <form #signupForm="ngForm" novalidate>
    <ion-list lines="none">
      <ion-item>
        <ion-label position="stacked" color="primary">Email</ion-label>
        <ion-input [(ngModel)]="signup.email" name="email" type="text" #emailCtrl="ngModel" required>
        </ion-input>
      </ion-item>
      <ion-text color="danger">
        <p [hidden]="emailCtrl.valid || submitted == false" class="ion-padding-start">
          Username is required
        </p>
      </ion-text>

      <ion-item>
        <ion-label position="stacked" color="primary">Password</ion-label>
        <ion-input [(ngModel)]="signup.password" name="password" type="password" #passwordCtrl="ngModel" required>
        </ion-input>
      </ion-item>
      <ion-text color="danger">
        <p [hidden]="passwordCtrl.valid || submitted == false" class="ion-padding-start">
          Password is required
        </p>
      </ion-text>
    </ion-list>

    <div class="ion-padding">
      <ion-button (click)="onSignup(signupForm)" type="submit" expand="block">Signup</ion-button>
    </div>
  </form>
</ion-content>

Add Login page with Google OAuth and Register user with email

On our login page we have demonstrated two options of Ionic firebase authentication, we have already created a signup page. Now let’s implement the consumer of our AuthService login with Google and email. Edit app.auth/login.page.ts file.

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Router } from '@angular/router';
import { IUser } from 'src/app/models/user';
import { AuthService } from '../../services/auth.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage {
  submitted = false;
  user = { email: '', password: '' };

  constructor(
    private router: Router,
    private authService: AuthService
  ) { }

  onLogin(form: NgForm): void {
    if (form.valid) {
      this.authService.loginWithEmail({ email: form.control.value.email, password: form.control.value.password });
    }
  }

  resetPassword(email: string): void {
    this.authService.resetPassword(email);
  }

  googleAuth(): void {
    this.authService.googleLogin();
  }


  onSignup(): void {
    this.router.navigateByUrl('/signup');
  }
}

On our login.page.ts file we have different methods like resetPassword, when the user forgot the password, he| or she can use resetPassword by specifying email. AngularFire auth provides us with lots of methods for an email confirmation and password reset. Specifying the email on reset password will send you a link to reset the user with a new password. Now let’s add a form with buttons for login, reset the password, and Google login in our app/auth/login.page.html file.

<ion-header>
  <ion-toolbar color="primary">
    <ion-title>Login</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <div class="login-container">
    <form #loginForm="ngForm" novalidate>
      <ion-list>
        <ion-item>
          <ion-label position="stacked" color="primary">Email</ion-label>
          <ion-input name="email" type="email" [(ngModel)]="user.email" #emailCtrl="ngModel" required>
          </ion-input>
        </ion-item>

        <ion-text color="danger">
          <p [hidden]="emailCtrl.valid || submitted == false" class="ion-padding-start">
            Email is required
          </p>
        </ion-text>

        <ion-item>
          <ion-label position="stacked" color="primary">Password</ion-label>
          <ion-input type="password" [(ngModel)]="user.password" name="password" #passwordCtrl="ngModel" required>
          </ion-input>
        </ion-item>

        <ion-text color="danger">
          <p [hidden]="passwordCtrl.valid || submitted == false" class="ion-padding-start">
            Password is required
          </p>
        </ion-text>
      </ion-list>

      <ion-row>
        <ion-col>
          <ion-button (click)="onLogin(loginForm)" type="submit" expand="block">Login</ion-button>
        </ion-col>
        <ion-col>
          <ion-button (click)="onSignup()" color="light" expand="block">Signup</ion-button>
        </ion-col>
      </ion-row>
      <ion-row>
        <ion-col offset="6"></ion-col>
        <ion-col>
          <ion-button fill="clear" [disabled]="!loginForm.control.value.email"
            (click)="resetPassword(loginForm.control.value.email)">Reset password</ion-button>
        </ion-col>
      </ion-row>
    </form>
    <ion-item-group class="ion-padding group">
      <ion-item class="ion-margin-vertical" (click)="googleAuth()">
        <ion-icon slot="start" name="logo-google" color="danger"></ion-icon>
        <ion-label>Continue with Google</ion-label>
        <ion-icon slot="end" name="arrow-forward-outline"></ion-icon>
      </ion-item>
    </ion-item-group>
  </div>
</ion-content>

Conclusion
In this article, we have explored how to implement Ionic firebase authentication using Google mail and login with email and password in Ioni Angular applications. AngularFire library is an official angular library to implement firebase activities like authentication, storing data, and manipulating data in firebase.

Related posts

How to implement ionic firebase authentication

One thought on “How to implement ionic firebase authentication

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top