
Fermin Perdomo
Full Stack Developer

Add Firebase Push Notifications to SaaS laravel Web App
If you’re building a restaurant SaaS platform with Laravel and want to notify staff in real-time when a customer places a new order or taps "Call Waiter", then this guide is for you!
We'll show you how to integrate Firebase Cloud Messaging (FCM) with a multi-tenant Laravel system and trigger push notifications to multiple devices — including Chrome on desktop, Android tablet, and Android mobile
Step 1: Firebase Setup
Go to Firebase Console
Create a new project (or use an existing one).
Navigate to Project Settings > Cloud Messaging tab.
Save your Server key and Sender ID.
Under General, add your web app and grab the Firebase config (apiKey, projectId, etc.)
Step 2: Laravel Backend Setup
1. Install FCM PHP package
Use the kreait/firebase-php package:
composer require kreait/firebase-php
2. Add FCM configuration
In .env
:
FCM_CREDENTIALS=/full/path/to/firebase-credentials.json
In config/services.php
:
'fcm' => [
'credentials' => env('FCM_CREDENTIALS'),
],
3. Create an FCM service class
// app/Services/FCMService.php
namespace App\Services;
use Kreait\Firebase\Factory;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;
class FCMService
{
protected $messaging;
public function __construct()
{
$factory = (new Factory)->withServiceAccount(config('services.fcm.credentials'));
$this->messaging = $factory->createMessaging();
}
public function sendToTokens(array $tokens, $title, $body, array $data = [])
{
$notification = Notification::create($title, $body);
$message = CloudMessage::new()
->withNotification($notification)
->withData($data);
return $this->messaging->sendMulticast($message, $tokens);
}
}
🧠 Step 3: Database Design
Create a model and migration to store FCM tokens:
php artisan make:model FCMToken -m
In create_f_c_m_tokens_table.php
:
Schema::create('f_c_m_tokens', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id');
$table->string('token');
$table->timestamps();
});
Then:
php artisan migrate
Step 4: Frontend Integration (HTML + JS)
1. Add Firebase SDK
In your layout blade or Vue component:
<script src="https://www.gstatic.com/firebasejs/9.6.10/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.6.10/firebase-messaging-compat.js"></script>
2. Firebase Initialization + Token Registration
<script>
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
projectId: "YOUR_PROJECT_ID",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID"
};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
async function initFCM(restaurantId) {
try {
const permission = await Notification.requestPermission();
if (permission === 'granted') {
const token = await messaging.getToken({
vapidKey: "YOUR_PUBLIC_VAPID_KEY"
});
await fetch('/api/register-fcm-token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
body: JSON.stringify({ token, restaurant_id: restaurantId })
});
}
} catch (err) {
console.error('FCM error:', err);
}
}
</script>
Step 5: Create API to Register Token
Route::post('/api/register-fcm-token', function (Request $request) {
$request->validate([
'token' => 'required',
'restaurant_id' => 'required|integer',
]);
\App\Models\FCMToken::updateOrCreate(
['token' => $request->token],
['restaurant_id' => $request->restaurant_id]
);
return response()->json(['success' => true]);
});
Step 6: Service Worker
In your public folder, create firebase-messaging-sw.js
:
importScripts('https://www.gstatic.com/firebasejs/9.6.10/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.6.10/firebase-messaging-compat.js');
firebase.initializeApp({
apiKey: "YOUR_API_KEY",
projectId: "YOUR_PROJECT_ID",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID"
});
const messaging = firebase.messaging();
messaging.onBackgroundMessage(function(payload) {
const { title, body } = payload.notification;
self.registration.showNotification(title, {
body: body,
data: payload.data
});
});
Make sure this is registered in your main JS:
navigator.serviceWorker.register('/firebase-messaging-sw.js')
.then((registration) => {
messaging.useServiceWorker(registration);
});
Step 7: Trigger Notifications from Laravel
In your controller when new order or “Call Waiter” occurs:
$tokens = FCMToken::where('restaurant_id', $restaurantId)->pluck('token')->toArray();
$title = "New Order!";
$body = "Table {$tableNumber} placed an order.";
$data = [
'restaurant_id' => $restaurantId,
'table_number' => $tableNumber,
];
app(FCMService::class)->sendToTokens($tokens, $title, $body, $data);