Google Firebase Authentication (Angular) step by Step

Firebase authentication is used to authenticate users of the application. Knowing a user's identity allows an app to manage data securely among users.
Firebase Authentication provides ready-made backend services for your web/mobile app.
Firebase authentication SDK provides methods to manage users' email addresses and passwords. Firebase authentication SDK also handles email reset password.
Apart from email and password, users can be authenticated using Google, Facebook, Twitter, Github, and phone number.

For this example, I will be using Email authentication and an Angular framework. If you are not familiar with angular you can also use Vanilla javascript or any Web framework of your choice.


1. create a project on firebase

log on to firebase and create a project, copy your project credentials on firebase and paste them on the enviroment.ts file.



export const environment = {
  production: false,
  firebase : {
    apiKey: "App_key",
    authDomain: "app_domain",
    databaseURL: "Databse_url",
    projectId: "project_id",
    storageBucket: "fir-demo-7719c.appspot.com",
    messagingSenderId: "433027347081",
    appId: "App_id"
  }
};

2. Generate a service class

We will use our service class to manage API calls for our application authentication. the below command with generates a service called auth-service.ts
$ ng generate service auth-service




3. install AngularFireAuth


The AngularFireAuth module which will give us a connection stream to firestore SDK.
for that, I will do the following
npm install AngularFireAuth --save I will also want to display a login error
in a toast, so I will install angular2-flash-messages .


4. Create a login and register component.

Generate login, registration, userModel and home component by running the following command.
 ng generate component Login 
 ng generate component Register 
 ng generate component Homepage 
 ng generate component Register 
 ng generate component Passwordreset 

The below file is our user-model which will be used in our registration file, note the import in our app.module.ts file

export class UserModel {
  emailstring;
  passwordstring;
  usernamestring ;
  createdTimestamp<Date> ;
}


5. Update [imports] in app.module.ts

configure   AngularFireModule.initializeApp(environment.firebase,'g-auth') update app.module.ts
with all neccessary imports.



import { AuthService } from
 './services/auth.service';
import { AngularFireAuth } 
from 'angularfire2/auth';

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {AngularFireModulefrom 'angularfire2';
import { environment } from 'src/environments/environment';
import {AngularFireAuthModulefrom 'angularfire2/auth';



import { AppComponent } from './app.component';
import {BrowserAnimationsModulefrom '@angular/platform-browser/animations';
import {ReactiveFormsModulefrom '@angular/forms';
import { FlashMessagesModule } from 'angular2-flash-messages';


import {FormsModulefrom '@angular/forms';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { PasswordresetComponent } from './passwordreset/passwordreset.component';
import { HomepageComponent } from './homepage/homepage.component';



@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    RegisterComponent,
    WelcomeComponent,
    PasswordresetComponent,
    HomepageComponent,
    


  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    ReactiveFormsModule,
    FormsModule,
    NgbModule,
    FormsModule ,
    HttpClientModule,
    AngularFirestoreModule,
    HttpClientModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    NgbModule.forRoot(),
    AngularFireModule.initializeApp(environment.firebase,'g-auth'),
    AngularFireDatabaseModule,
    MDBBootstrapModule.forRoot(),
    AngularFireAuthModule,
    Angular4PaystackModule,
    AngularFirestoreModule,
    ReactiveFormsModule,
    FlashMessagesModule.forRoot()


  ],
  providers: [AuthGuardServiceUsersServiceAdminAuthGuard,
    Enrollguard,NgbModalConfigNgbModal,
    InvestorsGuard, {provide: LocationStrategy,
 useClass: HashLocationStrategy},
     AuthServiceAngularFireAuth],
  bootstrap: [AppComponent]
})
export class AppModule { }



6. Structure auth-service.ts file and use import



import { UserModel } from './../models/user-model.model';
import { AngularFirestore } from '@angular/fire/firestore';
import { Routerfrom '@angular/router';
import { AngularFireAuth } from 'angularfire2/auth';
import { InjectableOnInit } from '@angular/core';
import * as firebase  from 'firebase';

import { AngularFireDatabase } from 'angularfire2/database';



export interface CurrentUserIde { idstring; }
@Injectable({
  providedIn: 'root'
})
export class AuthService {
  formDataUserModel;
  user$Observable <firebase.User>;


  constructor(
               public angularFireAuthAngularFireAuth,
               private routerRouter,
               private dbAngularFireDatabase,
               public routeActivatedRoute
               )  {
          this.user$ = angularFireAuth.authState;


  }


  async storeUserDetails(credentials) {
    return this.firestore.collection('users').add(credentials);


  }


 async createNewUser(emailstringpasswordstring) {
    return await this.angularFireAuth.auth
.createUserWithEmailAndPassword(emailpassword).thenvalue => {
      this.router.navigate(['/welcome']);
      this.sendEmailVerification();


    }).catch(err => {
    });


  } 


  async sendEmailVerification() {
    return await this.angularFireAuth
.auth.currentUser.sendEmailVerification();
  }



  async sendPasswordResetEmail(passwordResetEmailstring) {
    return await this.angularFireAuth.auth
.sendPasswordResetEmail(passwordResetEmail);
  }




  async logout() {
     return await this.angularFireAuth.auth.signOut();
  }



  isUserLoggedIn() {
    return JSON.parse(localStorage.getItem('user'));


  }

}




7.update login file

import { FlashMessagesService } from 'angular2-flash-messages';

import { RouterNavigationEndActivatedRoute } from '@angular/router';
import { AuthService } from './../services/auth.service';
import { ComponentOnInitHostBinding } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';



@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
  inValidLoginboolean;


  selectedValstring;
  responseMessage = '';
  responseMessageType = '';
  emailInputstring;
  passwordInputstring;
  isForgotPasswordboolean;
  userDetailsany;
  serverErrorstring;
  loadingboolean;


  constructor
(private usersServiceUsersService  ,
         private routeActivatedRoute,
         private angularFireAuthAngularFireAuth,
         private _flashMessageFlashMessagesService,
         private authServiceAuthServiceprivate routerRouter) {


    this.selectedVal = 'login';
    this.isForgotPassword = false;
  }


 // Check localStorage is having User Data
 isUserLoggedIn() {
  this.userDetails = this.authService.isUserLoggedIn();
}


async loginUser() {
  this.loading = true;
 let email = this.emailInput.toLowerCase();
  let password = this.passwordInput;
  console.log(emailpassword);
  const returnUrl  = this.route.snapshot.queryParamMap
.get('returnUrl') || '/welcome';


  return await this.angularFireAuth.auth.
signInWithEmailAndPasswordemailpassword).then(value => {
    this.loading = false;
    this.router.navigateByUrl(returnUrl);
    localStorage.setItem('currentUserEmail'email);
  }).catch(error => {
    this.loading = false;
    window.localStorage.clear();
    window.localStorage.removeItem('currentUserEmail');
    this._flashMessage.show(`${error.code}`,
    { cssClass: 'text-center bg-danger text-white  font-weight-bold',
timeout: 4000 });



  });


}


  ngOnInit() {

  }


}



8. Generate auth guard service

let us generate auth guard service, this will serve as a middleware to check if a user is authenticated, else send him
back to our login page. ng g guard authService


import { AuthService } from './auth.service';
import { Injectable } from '@angular/core';
import { CanActivateRouterRouterStateSnapshot } from '@angular/router';
import {mapfrom 'rxjs/operators';
import { AngularFirestore } from '@angular/fire/firestore';





@Injectable({
  providedIn: 'root'
})
export class AuthGuardService implements CanActivate  {



  constructor(
    private authAuthService,
    private routerRouter,
    ) {


  }
  canActivate(routestateRouterStateSnapshot){
  return this.auth.user$.pipe(map(user => {
    if(userreturn true;


    this.router.navigate(['/login'], {queryParams: {returnUrl: state.url}});
    return false;
  }));


  }
}

In the authGuardService file, we imported the AuthService. CanActivate, Router. rxjs map operator
and angular Firestore Module.
We then implement the Canactivate interface to determine if a route should be activated or not.
It will return true if a route is activated else it should return false and navigation will be
canceled.
We went ahead in our constructor and create an instance of our AuthService and Router class.
lastly we created the method [canActivate] with an argument [route] and [RouterStateSnapShot]
Then we check the firebase user and if a user is found we then return true, else did navigate
the user to the login page and return false while saving his return Url.
In the file, the app routing module uses the guard service as
  {path: '/homepage', component: MessageComponent,  canActivate: [AuthGuardService]},


9.RegistrationPage.ts


import { FlashMessagesService } from "angular2-flash-messages";
import { Observablefrom "rxjs";

import { RouterNavigationEnd } from "@angular/router";
import { AuthService } from "./../services/auth.service";
import { ComponentOnInitHostBindingOnDestroy } from "@angular/core";
import { FormGroupNgForm } from "@angular/forms";

import { AngularFireAuth } from "angularfire2/auth";



@Component({
  selector: "app-register",
  templateUrl: "./register.component.html",
  styleUrls: ["./register.component.scss"]
})
export class RegisterComponent implements OnInitOnDestroy {

  emailInputstring;
  passwordInputstring;
  userDetailsstring;
  phoneNumberany;
  loadingboolean;




  constructor(
    public authServiceAuthService,
    private routerRouter,
    private flashMessageFlashMessagesService,
    private angularFireAuthAngularFireAuth
  ) {
  }


  ngOnInit() {

  }



  resetForm(form?: NgForm) {
    if (form != null) {
      form.resetForm();
    }


    this.authService.formData = {
      fullname: "",
      email: "",
      password: "",
      mobile: null,
    };
  }


  async createNewUser(formNgForm) {
    this.loading = true;
    this.phoneNumber = form.value.mobile;
    let newEmailToLower = form.value.email;
    const regEmail = newEmailToLower.toLowerCase();
    const password = form.value.password;

 return await this.angularFireAuth.auth
      .createUserWithEmailAndPassword(regEmailpassword)
      .then(value => {
        this.router.navigate(["/welcomepag"]);
        this.loading = false;
        this.authService.sendEmailVerification();
        form.value.password = "";
        form.value.email.toLowerCase();
      })
      .catch(err => {
        console.log(err);
        this.flashMessage.show(`${err.code}`, {
          cssClass: "text-center bg-danger text-white  font-weight-bold",
          timeout: 4000
        });
        this.loading = false;
      });
  }

}


If true the successful user will be redirected to welcome page else we catch the error
and display the error to the error using flashMessage.
Note: while creating new user, firebase SDK is case sensitive, so we have to convert all our
emails to small letters.

10.RegistrationPage.html



<form #regform="ngForm" (submit)="createNewUser(regform)">
  <div class="simple-login-container jumbotron  text-white">
    <h2> Create Account</h2>

    <div class="row">
        <div class="col-md-12 form-group">
    <input type="email" id="email" name="email"
 [(ngModel)]="authService.formData.email" #email="ngModel" required
    class="form-control mb-4" placeholder="E-mail"  autocomplete="off">
        </div>
    </div>

    <div class="row">
        <div class="col-md-12 form-group">
     <input type="password" id="password"
 [(ngModel)]="authService.formData.password"  #password="ngModel"
     class="form-control mb-4" placeholder="Password"
  name="password" value="" required>
        </div>
    </div>


      <!-- flash msg -->
      <div class="container row justify-centent-center">
        <div class="flash">
          <flash-messages></flash-messages>
        </div>
      </div>
    <div class="row">
        <div class="col-md-12 form-group">
    <button class="btn btn-success btn-block "  [disabled]="( !regform.valid
      && password != password_conf)"
    id="submitBtn" type="submit"> <i class="fa fa-spinner  fa-spin" *ngIf=loading ></i>
   <small *ngIf="!loading" > Create Account</small> </button>
        </div>
    </div>

    <p> already a member?
      <a routerLink="/login">login</a>
    </p>

    <div class="row">
        <div class="col-md-12">
          <a [routerLink]="['/']" >home</a>
        </div>
    </div>
</div>

</form>




We created a form with a template variable #regform="ngForm" and we bind our
form submission to (submit)="createNewUser(regform)" .While we submit our form, we
assign the form values as follows
  this.phoneNumber = form.value.mobile;
    let newEmailToLower = form.value.email;
    const regEmail = newEmailToLower.toLowerCase();
    const password = form.value.password;

Next, we call the angularFireAuth and create a new user with Email and password.
You can go back to your firebase dashboard and see the new user-created.

Post a Comment

0 Comments