Search Lessons, Code Snippets, and Videos
search by algolia
X
#native_cta# #native_desc# Sponsored by #native_company#

Firebase Phone Authentication With Angular 4 Tutorial

Episode 29 written by Jeff Delaney
full courses for pro members

Signing up users with a phone number adds certain degree of trust or confidence to an app. In this lesson, we are going to use the new phone authentication paradigm from Firebase in our Angular 4 app. At this time, phone auth is not supported in AngularFire2, so we will use the firebase JavaScript SDK directly. Phone auth can also be used to link accounts, providing an effective solution for two-factor authentication.

Configuring the reCAPTCHA Widget in Angular

Firebase requires users to use reCAPTCHA to prevent abusive use of the API. You can also implement an invisible reCAPTCHA, but we will be using the visible version in this example.

visible recaptcha for firebase phone login angular 4

Injecting the Window Object

You will need to make a reference to the Window object, which represents the DOM. It is considered a bad practice to modify window directly inside a component - the same goes for all global browser objects. Angular apps can also run on mobile and desktop platforms (which don’t have a window), so a better alternative is to inject the window as a service.

Generate the service with ng g service window

import { Injectable } from '@angular/core';

@Injectable()
export class WindowService {

get windowRef() {
return window
}

}

Phone Login Component

phone auth sms text confirmation

ng g component phone-login

Now we need to collect the user’s phone number. The number must be submitted in E.164 format, which looks like +19495555555 for U.S. numbers.

In order keep values free of validation errors, I am breaking the from into four separate parts and creating a PhoneNumber class. Then I use a getter to combine the form values into a single string in E164 format.

PhoneNumber class

export class PhoneNumber {
country: string;
area: string;
prefix: string;
line: string;

// format phone numbers as E.164
get e164() {
const num = this.country + this.area + this.prefix + this.line
return `+${num}`
}

}

After the the confirmation text is sent, we display another form field for the user to enter the confirmation. Here’s a breakdown of the process step-by-step

  • User verifies reCAPTCHA
  • User submits their phone number.
  • Firebase sends SMS text and returns a confirmation object.
  • User verifies SMS code and the auth state is updated.

Result of successful Firebase phone auth Result of successful Firebase phone auth

phone-login.component.ts

import { Component, OnInit } from '@angular/core';
import { WindowService } from '../window.service';
import * as firebase from 'firebase';


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

windowRef: any;

phoneNumber = new PhoneNumber()

verificationCode: string;

user: any;

constructor(private win: WindowService) { }

ngOnInit() {
this.windowRef = this.win.windowRef
this.windowRef.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container')

this.windowRef.recaptchaVerifier.render()
}


sendLoginCode() {

const appVerifier = this.windowRef.recaptchaVerifier;

const num = this.phoneNumber.e164;

firebase.auth().signInWithPhoneNumber(num, appVerifier)
.then(result => {

this.windowRef.confirmationResult = result;

})
.catch( error => console.log(error) );

}

verifyLoginCode() {
this.windowRef.confirmationResult
.confirm(this.verificationCode)
.then( result => {

this.user = result.user;

})
.catch( error => console.log(error, "Incorrect code entered?"));
}


}

phone-login.component.html

In the HTML template, we trigger the various stages of the auth login with button clicks. The phone number object and the verification code are tracked with ngModel.

<div [hidden]="user">
<h1>Sign In with Your Phone Number</h1>

<label for="phone">Phone Number</label><br>
<input type="text" [(ngModel)]="phoneNumber.country" class="input" placeholder="1" maxlength="2">
<input type="text" [(ngModel)]="phoneNumber.area" class="input" placeholder="949" maxlength="3">
<input type="text" [(ngModel)]="phoneNumber.prefix" class="input" placeholder="555" maxlength="3">
<input type="text" [(ngModel)]="phoneNumber.line" class="input" placeholder="5555" maxlength="4">

<div id="recaptcha-container"></div>

<button (click)="sendLoginCode()">SMS Text Login Code</button>

<div *ngIf="windowRef.confirmationResult">
<hr>
<label for="code">Enter your Verification Code Here</label><br>
<input type="text" name="code" [(ngModel)]="verificationCode">

<button (click)="verifyLoginCode()">Verify</button>
</div>

</div>

<div *ngIf="user">
You have successfully logged in with your phone number!

UserId: {{ user?.uid }}

</div>