How to implement firebase google authentication in laravel?

Implementing Firebase Google Authentication in Laravel is a great way to allow users to sign in using their Google accounts.


Important Notes:


1. If you haven't set up a Firebase project or don't have the configuration keys, follow our guide on how to create a Firebase project and obtain the configuration file.


2. Setting Up Google Sign-In and Adding a Support Email

    Enable Google Sign-In :

            1. Head over to your Firebase project settings.

            2. Navigate to the Authentication section.

            3. Make sure you've enabled the 'Google' sign-in method.

    Support Email :

            1. To setup Web SDK configuration you need to add support email, So make sure to add that.


Step 1 : Update User Migration

To meet our specific requirements, we'll need to modify the user migration file. Please copy the migration code provided below and make any necessary updates. Afterward, run the migration command to apply the changes.

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('account_type');
    $table->string('mobile_no')->nullable();
    $table->string('email')->nullable();
    $table->timestamp('email_verified_at')->nullable();
    $table->string('password')->nullable();
    $table->string('profile')->nullable();
    $table->rememberToken();
    $table->timestamps();
});
Step 2 : Make Auth Controller

To create a controller please execute the provided command.

php artisan make:controller Firebase/GoogleAuthController
Step 3 : Create Routes.

Our next step involves constructing a login form and completing the login process. To begin, we'll create relevant routes in the 'web.php' file.

use App\Http\Controllers\Firebase\GoogleAuthController as FirebaseGoogleAuthController;


// FIREBASE AUTH ROUTES

// login / register will be same
Route::match(['POST','GET'],'login-with-google', [FirebaseGoogleAuthController::class, 'login'])->name('login-with-google');
Step 4 : Login / Register Form and Processing

We'll create a function named 'login' in 'Firebase/GoogleAuthController.php'. This function will be responsible for showing login form and process login.

public function login()
{
    return view('firebase.auth.login');
}

resources/views/firebase/auth/login.blade.php


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Firebase - Login with Google</title>
    <!-- BOOTSTRAP -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
    <!-- Styles -->
    <style>
        body {
            background: #f7f7f7;
        }

        .form-box {
            max-width: 500px;
            margin: auto;
            padding: 50px;
            background: #ffffff;
            border: 10px solid #f2f2f2;
            margin-top: 50px;
        }
    </style>
</head>
<body>

<!-- Login Form -->
<div class="form-box">
    <form action="{{ route('login-with-google') }}" method="POST" style="text-align: center;" id="login-form">
        @csrf
        <input type="hidden" name="name" id="name">
        <input type="hidden" name="email" id="email">
        <input type="hidden" name="profile" id="profile">
        <input type="hidden" name="mobile_no" id="mobile_no">
        <p id="login-error-message" class="text-danger"></p>
        <button type="button" id="login-btn" class="btn btn-danger">Login with Google</button>
    </form>
</div>

<!-- JQUERY, BOOTSTRAP -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<!-- FIREBASE : Initialize App -->
<script src="https://www.gstatic.com/firebasejs/8.4.1/firebase-app.js"></script>
<!-- FIREBASE : Auth -->
<script src="https://www.gstatic.com/firebasejs/8.4.1/firebase-auth.js"></script>

<!-- FIREBASE SCRIPT HERE -->

</body>
</html>
Step 5 : Initialize Script

Add this scripts on bottom of register /  login blade file.

<!-- Firebase : Initialize App -->
<script src="https://www.gstatic.com/firebasejs/8.4.1/firebase-app.js"></script>
<!-- Firebase : Auth -->
<script src="https://www.gstatic.com/firebasejs/8.4.1/firebase-auth.js"></script>

Now, let's initialize the app and begin working on the login script.

// initializing app
const firebaseConfig = {
    apiKey: "AIzaSy**********************",
    authDomain: "laravel**********************",
    projectId: "laravel**********************",
    storageBucket: "laravel**********************",
    messagingSenderId: "**********************",
    appId: "**********************"
};

firebase.initializeApp(firebaseConfig);


// on login button click
$(document).on('click','#login-btn',function(e) 
{
    e.preventDefault();
    const provider = new firebase.auth.GoogleAuthProvider();
    firebase.auth().signInWithPopup(provider).then(function (result) 
    {
        var token = result.credential.accessToken;
        var user = result.user;
        $('#name').val(user.displayName);
        $('#email').val(user.email);
        $('#profile').val(user.photoURL);
        $('#mobile_no').val(user.phoneNumber);
        $('#login-form').submit();
    });
});
Step 6 : Login / Register Function

After initializing script let's start by examining 'login' function the existing function in 'GoogleAuthController' that handles saving the details and completes login.

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;




public function login(Request $request)
{
    if($request->isMethod('POST'))
    {
        $user = User::where('email',$request->email)->first();

        if(empty($user->id))
        {
            $profile = self::save_file_from_url($request->profile);
            $postArr = [
                'account_type' => 'google',
                'name' => $request->name,
                'email' => $request->email,
                'mobile_no' => $request->mobile_no,
                'profile' => $profile,
            ];

            $user = User::updateOrCreate(
                [
                    'email' => $request->email
                ], $request->merge($postArr)->except(['_token'])
            );
        }

        Auth::login($user);

        return redirect()->route('home');
    }

    return view('firebase.auth.login');
}

Make sure to add fillable in User.php

protected $fillable = [
    'name',
    'account_type',
    'mobile_no',
    'email',
    'password',
    'profile',
];

Shall we create a new function called 'save_file_from_url'? This function will handle saving profile images from Google accounts. If you're interested in this function, we've already posted detailed information about it. Feel free to check it out.

use Illuminate\Support\Facades\Storage;



public static function save_file_from_url($url)
{
    $sizeData = getimagesize($url);
    $extension = image_type_to_extension($sizeData[2]);

    $filename = time() . rand(1,9999) . $extension;
    Storage::disk('local')->put($filename, file_get_contents($url));

    return $filename;
}