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

  1. Go to Firebase Console

  2. Create a new project (or use an existing one).

  3. Navigate to Project Settings > Cloud Messaging tab.

  4. Save your Server key and Sender ID.

  5. 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);
                                        
                                    


Login

To leave a reaction, you need to log in.