Chapter 14 - Social Login with Firebase

Hello Artisan's, welcome to the 14th chapter of being an Artisanary. In this chapter we'll show how to add social login with firebase in our laravel project. So if you already complete the previous chapters/sections, then you're good to go, if not my recommendation would be please complete the previous chapters. Because we'll use the same old repository that we use from chapter 4. 

Note: Tested on Laravel 10.0

Table of Contents

  1. Modify users table and User Model 
  2. Create and Setup Controller
  3. Setup Route
  4. Setup Firebase and View File
  5. Output

Modify users table and User Model

At first we need to add a new column to our users table. And for that we need to create a new migration file. So, fire the below command in terminal

php artisan make:migration add_firebase_auth_id_to_users_table

It'll create a file called 2023_04_23_101553_add_firebase_auth_id_to_users_table.php under “database/migrations”. Open the file and replace with the below code.

2023_04_23_101553_add_firebase_auth_id_to_users_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('firebase_auth_id')->nullable();
        });
    }

    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            //
        });
    }
};

After that we've to update our $fillable property in our User.php model like below.

app/Models/User.php
		protected $fillable = [
        'name',
        'email',
        'password',
        'role_id',
        'role_id',
        'firebase_auth_id'
    ];

Create and Setup Controller

Now we need to write our logic to login our user to the system. Add the below function to app/Http/Controllers/ProfileController.php

public function socialLogin(Request $request): \Illuminate\Http\JsonResponse
    {
        try {
            $user = User::where('firebase_auth_id', $request->uid)->orWhere('email',$request->email)->first();
            if ($user) {
                Auth::login($user);
            } else {
                $newUser = User::create([
                    'name' => $request->name,
                    'email' => $request->email,
                    'email_verified_at' => now(),
                    'firebase_auth_id' => $request->uid,
                    'password' => bcrypt('123456dummy'),
                    'role_id' => '1'
                ]);
                Auth::login($newUser);
            }
            return response()->json([
                'success' => 'User logged in successfully',
                'user' => Auth::user(),
                'route' => route('dashboard')
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'error' => $e->getMessage(),
            ]);
        }
    }

Setup Route

Now put the below route to routes/web.php

Route::post('social-login',[ProfileController::class,'socialLogin'])->name('social.login');

After putting the above route the whole file should look like below

routes/web.php
<?php

use App\Http\Controllers\BlogController;
use App\Http\Controllers\ProfileController;
use App\Http\Controllers\RoleController;
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');

Route::post('social-login',[ProfileController::class,'socialLogin'])->name('social.login');
Route::middleware(['auth','permission'])->group(function () {
    Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
    Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');

    Route::resource('blogs', BlogController::class)->except(['show']);
    Route::resource('roles', RoleController::class)->except(['show','create']);
    Route::resource('users', UserController::class)->except(['show','create']);
});

require __DIR__.'/auth.php';

Setup Firebase and View File

So, before setup the login.blade.php, we need to setup our firebase first. So go to this link and follow the screenshot below  

first click on the Add Project

Then enter a name and click Continue

Here you don't need to do anything. Just click on Continue

Choose an account for creating project and click Create Project to create project

After create it'll redirect you to the project page. From there click on web

Now we need to add “Firebase to our we app”. Enter name click on “Register App”

After clicking on “Register App” you'll see the below screen

 

Now Click on “Use a <script> tag” Radio Button. You'll see the below screen

Copy the firebaseConfig object somewhere else.

Now replace the content of the resources/views/auth/login.blade.php with the below contents.

login.blade.php
@extends('backend.layouts.base')
@section('title', __('Login'))
@section('base.content')
    <div class="login-box">
        <div class="login-logo">
            <a href="../../index2.html"><b>Admin</b>LTE</a>
        </div>

        <div class="card">
            <div class="card-body login-card-body">
                <p class="login-box-msg">Sign in to start your session</p>
                <form action="{{ route('login') }}" method="post">@csrf
                    <div class="input-group">
                        <input type="email" name="email" class="form-control" placeholder="Email">
                        <div class="input-group-append">
                            <div class="input-group-text">
                                <span class="fas fa-envelope"></span>
                            </div>
                        </div>
                    </div>
                    <span class="text-danger">{{ $errors->first('email') }}</span>
                    <div class="input-group mt-3">
                        <input type="password" name="password" class="form-control" placeholder="Password">
                        <div class="input-group-append">
                            <div class="input-group-text">
                                <span class="fas fa-lock"></span>
                            </div>
                        </div>
                    </div>
                    <span class="text-danger">{{ $errors->first('password') }}</span>
                    <div class="row mt-3">
                        <div class="col-12">
                            <button type="submit" class="btn btn-primary btn-block">Sign In</button>
                        </div>
                    </div>
                </form>
                <div class="social-auth-links text-center mb-3" id="firebaseui-auth-container">

                </div>
                <p class="mb-0">
                    <a href="{{ route('register') }}" class="text-center">Register a new membership</a>
                </p>
            </div>

        </div>
    </div>
@endsection
@push('css')
    <link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth.css" />
@endpush
@push('js')
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-auth.js"></script>
    <script src="https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth.js"></script>
    <script>
    //replace the below object which we'll copy earlier
        const firebaseConfig = {
            apiKey: "AIzaSyBITQn4jU802VIvoaTTFHsv6bm9HKp86b8",
            authDomain: "artisanary-4a9d3.firebaseapp.com",
            projectId: "artisanary-4a9d3",
            storageBucket: "artisanary-4a9d3.appspot.com",
            messagingSenderId: "154070063718",
            appId: "1:154070063718:web:af0b346ba2c8c5f0e22ba7",
            measurementId: "G-2NK43TXPYY"
        };

        // Initialize Firebase
        firebase.initializeApp(firebaseConfig);

        var ui = new firebaseui.auth.AuthUI(firebase.auth());
        var uiConfig = {
            callbacks: {
                signInSuccessWithAuthResult: function (authResult, redirectUrl) {
                    let response = authResult.additionalUserInfo.profile;

                        var data = {
                                uid: authResult.user.uid,
                            name: response.name,
                            email: response.email,
                            picture: response.picture,
                            phone: authResult.user.phoneNumber,
                            _token: '{{ csrf_token() }}',
                        };

                    $.ajax({
                        url: "{{ route('social.login') }}",
                        type: 'POST',
                        data: data,
                        success: function (response) {
                            if (response.success) {
                                window.location.href = response.route;
                            } else {
                                alert(response.error);
                            }
                        },
                        error: function (error) {
                            alert('Something Went Wrong');
                            window.location.reload();
                        }
                    });
                    return true;
                }
            },
            signInFlow: 'popup',
            signInSuccessUrl: '#',
            signInOptions: [
                {
                    provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID,
                    scopes: [
                        'https://www.googleapis.com/auth/contacts.readonly',
                        'https://www.googleapis.com/auth/user.birthday.read',
                        'https://www.googleapis.com/auth/user.gender.read',
                        'https://www.googleapis.com/auth/user.phonenumbers.read'
                    ],
                }
            ]
        };
        ui.start('#firebaseui-auth-container', uiConfig);
    </script>
@endpush

Ok now our firebase setup is done. Now we need to enable the social platform in the firebase panel. See the below screenshots

Now as our example purpose we'll see the "Google" Login. So click to “Google” and enable according to the below screenshot

And that's it. We've successfully configure the firebase app into our laravel project.

Output

And finally we're ready with our setup. It's time to check our output. Now if you go to http://localhost:8000/login, If everything goes well you'll find a below output.

N.B. We need to visit through localhost/https live server, either firebase will not work. And in the firebase all social login procedure is same. Check their docs here.

So, We saw the social login using Firebase. And yes keep up to date with the Github repository. If you face any difficulty, ping me in comment box. That's it for today. See you in my next chapter. Happy coding 🙂.