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.
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();
});
To create a controller please execute the provided command.
php artisan make:controller Firebase/GoogleAuthController
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');
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>
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();
});
});
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;
}