Firebase phone authentication example in Laravel 8

Firebase is a realtime cloud-hosted NoSQL database platform developed by Google. With Firebase, you can create real-time chat application, send notification and lots of stuff. Firebase offers free services up to some limits.

In this tutorial, I will share you how you can add OTP feature in authentication system in Laravel 8. This will add extra security to user account.

We will start from step by step from starting. So let's start from creating Firebase account.

Step 1: Firebase account and authentication

First of all create a account at Firebase. Then you will need to create a project in Firebase. Once you have created account. You need to enable phone authentication.

We also need to download the Firebase config file from project's apps from project settings page. We need this config file to configure your app to use Firebase. It is credentials of firebase project like that. We will put this file into blade view.

const config = {
    apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    authDomain: "XXXXXXXXX.firebaseapp.com",
    databaseURL: "XXXXXXXXX.firebaseio.com",
    projectId: "XXXXXXXXX",
    storageBucket: "XXXXXXXXX.appspot.com",
    messagingSenderId: "XXXX",
    appId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    measurementId: "XXXXXX"
};

Step 2: Create Laravel application

In the second step, we create Laravel 8 application using composer command. So Open your Terminal and run below command:

composer create-project laravel/laravel firebase

And change current directory to project root

cd firebase

Step 3: Create controller

In this step, we will create a controller using artisan command. So run below command to create controller.

php artisan make:controller FirebaseController

It will create a controller file at app/Http/Controllers/FirebaseController.php. Now open that file and add otp method.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FirebaseController extends Controller
{
    /**
     * otp view.
     *
     * @return view
     */
    public function otp()
    {
        return view('otp');
    }
}

Step 4: Create route

We need to create a route to handle controller method. So open routes/web.php file and add new route.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FirebaseController;

Route::get('otp', [FirebaseController::class, 'otp'])->name('otp');

Step 5: Create blade view

In this step, we will create a blade view otp.blade.php in resources/views directory. In this blade view we will include Firebase Javascript code for send and verify OTP. We will use Firebase CDN so we can user Firebase without installing in project.

otp.blade.php

<!doctype html>
<html>
    <head>
        <title>Phone number authentication</title>
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
        <style type="text/css">
            .hide {
                display: none;
            }
        </style>
    </head>
<body>  
    <div class="container">
        <h1 class="text-center m-3">Phone number authentication</h1>
        <div class="alert alert-danger hide" id="error-message"></div>
        <div class="alert alert-success hide" id="sent-message"></div>
        <div class="card">
            <div class="card-body">
                <form>
                    <div class="mb-3">
                        <label for="phone-number" class="form-label">Phone Number:</label>
                        <input type="text" id="phone-number" class="form-control" placeholder="+1XXXXXXXXXX">
                    </div>
                    <div id="recaptcha-container"></div>
                    <button type="button" class="btn btn-info" onclick="otpSend();">Send OTP</button>
                </form>
            </div>
        </div>
        <div class="card mt-3">
            <div class="card-body">
                <form>
                    <div class="mb-3">
                        <label for="otp-code" class="form-label">OTP code:</label>
                        <input type="text" id="otp-code" class="form-control" placeholder="Enter OTP Code">
                    </div>
                    <button type="button" class="btn btn-info" onclick="otpVerify();">Verify OTP</button>
                </form>
            </div>
        </div>
    </div>  
    <script src="https://www.gstatic.com/firebasejs/8.9.1/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.9.1/firebase-auth.js"></script>
    <script type="text/javascript">
        const config = {
            apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            authDomain: "XXXXXXXXX.firebaseapp.com",
            databaseURL: "XXXXXXXXX.firebaseio.com",
            projectId: "XXXXXXXXX",
            storageBucket: "XXXXXXXXX.appspot.com",
            messagingSenderId: "XXXX",
            appId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            measurementId: "XXXXXX"
        };
        
        firebase.initializeApp(config);
    </script>
    <script type="text/javascript">  
        // reCAPTCHA widget    
        window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
            'size': 'invisible',
            'callback': (response) => {
                // reCAPTCHA solved, allow signInWithPhoneNumber.
                onSignInSubmit();
            }
        });

        function otpSend() {
            var phoneNumber = document.getElementById('phone-number').value;
            const appVerifier = window.recaptchaVerifier;
            firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
                .then((confirmationResult) => {
                    // SMS sent. Prompt user to type the code from the message, then sign the
                    // user in with confirmationResult.confirm(code).
                    window.confirmationResult = confirmationResult;

                    document.getElementById("sent-message").innerHTML = "Message sent succesfully.";
                    document.getElementById("sent-message").classList.add("d-block");
                }).catch((error) => {
                    document.getElementById("error-message").innerHTML = error.message;
                    document.getElementById("error-message").classList.add("d-block");
                });
        }

        function otpVerify() {
            var code = document.getElementById('otp-code').value;
            confirmationResult.confirm(code).then(function (result) {
                // User signed in successfully.
                var user = result.user;

                document.getElementById("sent-message").innerHTML = "You are succesfully logged in.";
                document.getElementById("sent-message").classList.add("d-block");
      
            }).catch(function (error) {
                document.getElementById("error-message").innerHTML = error.message;
                document.getElementById("error-message").classList.add("d-block");
            });
        }
    </script>
</body>
</html>

In the above blade, we first create Firebase app instance using firebase.initializeApp() method. An invisible recaptcha is also loaded. we call Javascript otpSend() method when user click send OTP button and otpVerify() method when user click Verify OTP button.

Now everything is ready for testing. From the Terminal, run Laravel server using artisan command.

php artisan serve

In your web browser, go to http://localhost:8000/otp and try it. For debugging purpose, open and keep watch on browser console.

I hope you liked this article.

Was this article helpful?

0 out of 0 person found this article helpful.

Leave a comment

Or

No Comment