Learn how to integrate Firebase Cloud Messaging (FCM) with Laravel to send real-time web and mobile push notifications.
Push notifications have become an essential tool for increasing user engagement and retention. Whether you're building a mobile app or a progressive web app (PWA), sending real-time alerts is crucial. In this comprehensive guide, you'll learn how to set up Laravel Firebase push notifications using Firebase Cloud Messaging (FCM)βstep by step.
π Why Use Firebase with Laravel?
Firebase Cloud Messaging is a free and reliable cross-platform solution from Google that enables you to send notifications and messages to devices. Laravel, being a powerful PHP framework, can easily integrate with Firebase, allowing your backend to trigger web push notifications and mobile alerts to individual users or groups.
By the end of this tutorial, youβll have a working setup that supports:
- Laravel backend sending FCM push notifications.
- Web clients receiving real-time browser alerts.
- Storing and managing FCM tokens in the database.
π Prerequisites
Before you dive into the code, ensure you have:
- Laravel 8 or higher installed.
- A Firebase account (Firebase Console).
- Composer, Node.js, and npm installed.
- Basic understanding of PHP, Laravel, and JavaScript.
π§ Step 1: Set Up Firebase Project
1.1 Create a Firebase Project
Head to the Firebase Console.
Click on Add Project, name it (e.g., ExampleApp), and follow the prompts.
Take note of the Project ID under Project Settings > General.
1.2 Generate Service Account Key
Go to Settings > Service Accounts.
Click Generate new private key.
Rename and store the downloaded JSON file as firebase_credentials.json in storage/app/firebase/.
1.3 Add a Web App
In the Firebase console, go to Project Settings > General.
Click the </> icon to add a web app and copy the config object:
{ "apiKey": "your-api-key", "authDomain": "your-auth-domain", "projectId": "your-project-id", "storageBucket": "your-storage-bucket", "messagingSenderId": "your-messaging-sender-id", "appId": "your-app-id", "measurementId": "your-measurement-id" }
1.4 Retrieve the VAPID Key
Under Cloud Messaging > Web Push certificates, copy your Public Key (VAPID key). You'll need this in the frontend.
βοΈ Step 2: Configure Laravel Project
2.1 Add Environment Variables
Update your .env file:
FIREBASE_CREDENTIALS=app/firebase/firebase_credentials.json FIREBASE_PROJECT_ID=example-app FIREBASE_VAPID_KEY=your-vapid-key-here
2.2 Update config/services.php
'firebase' => [ 'credentials' => storage_path(env('FIREBASE_CREDENTIALS')), 'project_id' => env('FIREBASE_PROJECT_ID'), ],
2.3 Modify Users Table for FCM Tokens
Run the migration:
php artisan make:migration add_fcm_token_to_users_table
Then, in the migration file:
Schema::table('users', function (Blueprint $table) { $table->string('fcm_token')->nullable(); });
Apply it:
php artisan migrate
2.4 Install Google Auth Library
composer require google/auth
π‘ Step 3: Create Firebase Notification Service
Create a service class app/Services/Notifications/FireBase.php:
<?php namespace App\Services\Notifications; use Exception; use Google\Auth\Credentials\ServiceAccountCredentials; use GuzzleHttp\Client; class FireBase { public static function send($heading, $message, $deviceIds, $data = []) { $deviceIds = array_values(array_filter($deviceIds)); if (empty($deviceIds)) { throw new Exception('No device IDs provided'); } $scopes = ['https://www.googleapis.com/auth/firebase.messaging']; $credentials = new ServiceAccountCredentials($scopes, config('services.firebase.credentials')); $accessToken = $credentials->fetchAuthToken()['access_token']; $projectId = config('services.firebase.project_id'); $messagePayload = [ 'notification' => [ 'title' => $heading, 'body' => $message, ], 'android' => [ 'priority' => 'high', 'notification' => [ 'sound' => 'default', ], ], 'apns' => [ 'payload' => [ 'aps' => [ 'sound' => 'default', ], ], ], ]; if (!empty($data)) { $messagePayload['data'] = $data; } $messagePayload += count($deviceIds) > 1 ? ['tokens' => $deviceIds] : ['token' => $deviceIds[0]]; $payload = ['message' => $messagePayload]; $url = "https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send"; $client = new Client(); return $client->request('POST', $url, [ 'headers' => [ 'Authorization' => 'Bearer ' . $accessToken, 'Accept' => 'application/json', 'Content-Type' => 'application/json', ], 'json' => $payload, ]); } }
π₯οΈ Step 4: Frontend Setup for Web Push Notifications
4.1 Add Firebase Messaging Script
In your Blade template (layouts/app.blade.php):
<script type="module"> import { initializeApp } from "https://www.gstatic.com/firebasejs/11.0.1/firebase-app.js"; import { getMessaging, getToken, onMessage } from "https://www.gstatic.com/firebasejs/11.0.1/firebase-messaging.js"; const firebaseConfig = { apiKey: "your-api-key", authDomain: "your-auth-domain", projectId: "your-project-id", storageBucket: "your-storage-bucket", messagingSenderId: "your-messaging-sender-id", appId: "your-app-id", measurementId: "your-measurement-id" }; const app = initializeApp(firebaseConfig); const messaging = getMessaging(app); async function initFirebaseMessagingRegistration() { try { const permission = await Notification.requestPermission(); if (permission === 'granted') { const token = await getToken(messaging, { vapidKey: "{{ env('FIREBASE_VAPID_KEY') }}" }); if (token) { await axios.post("{{ route('firebase.token') }}", { _method: "PATCH", fcm_token: token }); } } } catch (err) { console.error("FCM Token error:", err); } } onMessage(messaging, ({ notification }) => { new Notification(notification.title, { body: notification.body }); }); initFirebaseMessagingRegistration(); </script>
4.2 Create the Service Worker
Save this as public/firebase-messaging-sw.js:
importScripts("https://www.gstatic.com/firebasejs/8.3.2/firebase-app.js"); importScripts("https://www.gstatic.com/firebasejs/8.3.2/firebase-messaging.js"); firebase.initializeApp({ apiKey: "your-api-key", authDomain: "your-auth-domain", projectId: "your-project-id", storageBucket: "your-storage-bucket", messagingSenderId: "your-messaging-sender-id", appId: "your-app-id", measurementId: "your-measurement-id", }); const messaging = firebase.messaging(); messaging.onBackgroundMessage(({ data: { title, body, icon } }) => { self.registration.showNotification(title, { body, icon }); });
π© Store FCM Tokens in Database
Create Route and Controller
Route:
Route::patch('/firebase/token', [App\Http\Controllers\FirebaseController::class, 'updateToken'])->name('firebase.token');
Controller:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class FirebaseController extends Controller { public function updateToken(Request $request) { Auth::user()->update(['fcm_token' => $request->fcm_token]); return response()->json(['success' => true]); } }
βοΈ Sending Laravel Push Notifications via Firebase
You can now send notifications using the FireBase service class:
use App\Services\Notifications\FireBase; FireBase::send( 'Hello User!', 'This is your Laravel Firebase push notification.', ['user-fcm-token-here'], ['customKey' => 'customValue'] );
π οΈ Troubleshooting Common Issues
- Notification Permission Denied: Make sure users allow browser notifications.
- Invalid Token: Check if FCM tokens are correctly stored.
- Firebase Errors: Double-check your API key, VAPID key, and service account JSON.
- 403 or Auth Errors: Ensure the Firebase service account JSON is correctly set and readable.
π’ Final Thoughts
Setting up Laravel push notifications with Firebase Cloud Messaging unlocks a powerful toolset for improving user experience. Whether you're targeting mobile apps or web browsers, FCM and Laravel make a reliable and scalable combination.
β Now youβre ready to build apps that notify your users instantly and keep them engaged!
π¬ Contact
For any questions, support, or collaboration, feel free to reach out through the following channels:
π§ Email: shishirjeishanul@gmail.com
π¬ WhatsApp: Chat on WhatsApp
π» GitHub (Main Profile): github.com/jeishanul
π¦ Project Repository: Laravel Firebase Notification on GitHub
Top comments (0)