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 {
email: string;
password: string;
username: string ;
created: Timestamp<Date> ;
}
5. Update [imports] in app.module.ts
configure AngularFireModule.initializeApp(environment.firebase,'g-auth') update app.module.tswith all neccessary imports.
import { AuthService } from
'./services/auth.service';
'./services/auth.service';
import { AngularFireAuth }
from 'angularfire2/auth';
from 'angularfire2/auth';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {AngularFireModule} from 'angularfire2';
import { environment } from 'src/environments/environment';
import {AngularFireAuthModule} from 'angularfire2/auth';
import { AppComponent } from './app.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {ReactiveFormsModule} from '@angular/forms';
import { FlashMessagesModule } from 'angular2-flash-messages';
import {FormsModule} from '@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: [AuthGuardService, UsersService, AdminAuthGuard,
Enrollguard,NgbModalConfig, NgbModal,
InvestorsGuard, {provide: LocationStrategy,
useClass: HashLocationStrategy},
useClass: HashLocationStrategy},
AuthService, AngularFireAuth],
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 { Router} from '@angular/router';
import { AngularFireAuth } from 'angularfire2/auth';
import { Injectable, OnInit } from '@angular/core';
import * as firebase from 'firebase';
import { AngularFireDatabase } from 'angularfire2/database';
export interface CurrentUserIde { id: string; }
@Injectable({
providedIn: 'root'
})
export class AuthService {
formData: UserModel;
user$: Observable <firebase.User>;
constructor(
public angularFireAuth: AngularFireAuth,
private router: Router,
private db: AngularFireDatabase,
public route: ActivatedRoute
) {
this.user$ = angularFireAuth.authState;
}
async storeUserDetails(credentials) {
return this.firestore.collection('users').add(credentials);
}
async createNewUser(email: string, password: string) {
return await this.angularFireAuth.auth
.createUserWithEmailAndPassword(email, password).then( value => {
.createUserWithEmailAndPassword(email, password).then( value => {
this.router.navigate(['/welcome']);
this.sendEmailVerification();
}).catch(err => {
});
}
async sendEmailVerification() {
return await this.angularFireAuth
.auth.currentUser.sendEmailVerification();
.auth.currentUser.sendEmailVerification();
}
async sendPasswordResetEmail(passwordResetEmail: string) {
return await this.angularFireAuth.auth
.sendPasswordResetEmail(passwordResetEmail);
.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 { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { AuthService } from './../services/auth.service';
import { Component, OnInit, HostBinding } 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 {
inValidLogin: boolean;
selectedVal: string;
responseMessage = '';
responseMessageType = '';
emailInput: string;
passwordInput: string;
isForgotPassword: boolean;
userDetails: any;
serverError: string;
loading: boolean;
constructor
(private usersService: UsersService ,
(private usersService: UsersService ,
private route: ActivatedRoute,
private angularFireAuth: AngularFireAuth,
private _flashMessage: FlashMessagesService,
private authService: AuthService, private router: Router) {
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(email, password);
const returnUrl = this.route.snapshot.queryParamMap
.get('returnUrl') || '/welcome';
.get('returnUrl') || '/welcome';
return await this.angularFireAuth.auth.
signInWithEmailAndPassword( email, password).then(value => {
signInWithEmailAndPassword( email, password).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 });
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 { CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import {map} from 'rxjs/operators';
import { AngularFirestore } from '@angular/fire/firestore';
@Injectable({
providedIn: 'root'
})
export class AuthGuardService implements CanActivate {
constructor(
private auth: AuthService,
private router: Router,
) {
}
canActivate(route, state: RouterStateSnapshot){
return this.auth.user$.pipe(map(user => {
if(user) return 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 { Observable} from "rxjs";
import { Router, NavigationEnd } from "@angular/router";
import { AuthService } from "./../services/auth.service";
import { Component, OnInit, HostBinding, OnDestroy } from "@angular/core";
import { FormGroup, NgForm } from "@angular/forms";
import { AngularFireAuth } from "angularfire2/auth";
@Component({
selector: "app-register",
templateUrl: "./register.component.html",
styleUrls: ["./register.component.scss"]
})
export class RegisterComponent implements OnInit, OnDestroy {
emailInput: string;
passwordInput: string;
userDetails: string;
phoneNumber: any;
loading: boolean;
constructor(
public authService: AuthService,
private router: Router,
private flashMessage: FlashMessagesService,
private angularFireAuth: AngularFireAuth
) {
}
ngOnInit() {
}
resetForm(form?: NgForm) {
if (form != null) {
form.resetForm();
}
this.authService.formData = {
fullname: "",
email: "",
password: "",
mobile: null,
};
}
async createNewUser(form: NgForm) {
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(regEmail, password)
.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
[(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"
[(ngModel)]="authService.formData.password" #password="ngModel"
class="form-control mb-4" placeholder="Password"
name="password" value="" required>
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.
0 Comments