Laravel 11 Firebase Push Notification (Mobile Application with Flutter)


This documentation is for implementing Laravel backend push notifications for a Flutter mobile application. This feature enables sending live notifications to users
Step 01: Set up functionality for Firebase
\>Download the JSON file from Firebase
\>Install (composer require kreait/laravel-firebase)
\>migrate and model the file, make
>Route File for managing the token, device_id
\>Route for push notification
\>Helper Function
Step 02: Set up environment credentials
.env file edit the file name
FIREBASE_CREDENTIALS=app/private/your-firebase-private-file-name.json
Step 03: Set up migration, model ,and user model relationships
create_firebase_tokens_table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('firebase_tokens', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->nullable()->constrained()->cascadeOnUpdate()->restrictOnDelete();
$table->longText('token');
$table->longText('device_id');
$table->enum('status', ['active', 'inactive'])->default('active');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('firebase_tokens');
}
};
Set up FirebaseToken model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class FirebaseToken extends Model
{
use HasFactory;
protected $guarded = [];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
Setup User model relationship
public function firebaseTokens()
{
return $this->hasMany(FirebaseToken::class);
}
Step 04: Create Controller logic
FirebaseTokenController.php
<?php
namespace App\Http\Controllers\Api\Backend;
use Exception;
use App\Models\User;
use App\Helper\Helper;
use Illuminate\Http\Request;
use App\Models\FirebaseToken;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
class FirebaseTokenController extends Controller
{
public function test()
{
$user = User::find(auth('api')->user()->id);
if ($user && $user->firebaseTokens) {
$notifyData = [
'title' => "test title",
'body' => "test body",
'icon' => env('APP_ICON')
];
foreach ($user->firebaseTokens as $firebaseToken) {
Helper::sendNotifyMobile($firebaseToken->token, $notifyData);
}
}
return response()->json([
'status' => true,
'message' => 'Token saved successfully',
'data' => $user ? $user->firebaseTokens : [],
'code' => 200,
], 200);
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'token' => 'required|string',
'device_id' => 'required|string',
]);
if ($validator->fails()) {
return response()->json(['message' => $validator->errors()->first()], 400);
}
$firebase = FirebaseToken::where('user_id', auth('api')->user()->id)
->where('device_id', $request->device_id)
->first();
if ($firebase) {
$firebase->delete();
}
try {
$data = new FirebaseToken();
$data->user_id = auth('api')->user()->id;
$data->token = $request->token;
$data->device_id = $request->device_id;
$data->status = "active";
$data->save();
return response()->json([
'status' => true,
'message' => 'Token saved successfully',
'data' => $data,
'code' => 200,
], 200);
} catch (Exception $e) {
return response()->json([
'status' => false,
'message' => 'No records found',
'code' => 418,
'data' => [],
], 418);
}
}
public function getToken(Request $request)
{
$validator = Validator::make($request->all(), [
'device_id' => 'required|string',
]);
if ($validator->fails()) {
return response()->json(['message' => $validator->errors()->first()], 400);
}
$user_id = auth('api')->user()->id;
$device_id = $request->device_id;
$data = FirebaseToken::where('user_id', $user_id)
->where('device_id', $device_id)
->get();
if (!$data) {
return response()->json([
'status' => false,
'message' => 'No records found',
'code' => 404,
'data' => [],
], 404);
}
return response()->json([
'status' => true,
'message' => 'Token fetched successfully',
'data' => $data,
'code' => 200,
], 200);
}
public function deleteToken(Request $request)
{
$validator = Validator::make($request->all(), [
'device_id' => 'required|string',
]);
if ($validator->fails()) {
return response()->json(['message' => $validator->errors()->first()], 400);
}
$user = FirebaseToken::where('user_id', auth('api')->user()->id)
->where('device_id', $request->device_id)
->first();
if ($user) {
$user->delete();
return response()->json([
'status' => true,
'message' => 'Token deleted successfully',
'code' => 200,
], 200);
} else {
return response()->json([
'status' => false,
'message' => 'No records found',
'code' => 404,
], 404);
}
}
}
Step 05: Set up routes
app.php file (Those routes should be in the authenticated routes)
// Firebase Token Module
Route::get("firebase/test", [FirebaseTokenController::class, 'test']);
Route::post("firebase/token/add", [FirebaseTokenController::class, 'store']);
Route::post("firebase/token/get", [FirebaseTokenController::class, 'getToken']);
Route::post("firebase/token/delete", [FirebaseTokenController::class, 'deleteToken']);
Step 06: Set up Helper logic
Helper.php file
use Illuminate\Support\Str;
use Kreait\Firebase\Factory;
use Illuminate\Support\Facades\Log;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;
public static function sendNotifyMobile($token, $notifyData): void
{
try {
$factory = (new Factory)->withServiceAccount(storage_path(env('FIREBASE_CREDENTIALS')));
$messaging = $factory->createMessaging();
$notification = Notification::create($notifyData['title'], Str::limit($notifyData['body'], 100), $notifyData['icon']);
$message = CloudMessage::withTarget('token', $token)->withNotification($notification);
$messaging->send($message);
} catch (Exception $exception) {
Log::error($exception->getMessage());
}
return;
}
Step 07: Test using Postman tool
Need a device ID and token
Subscribe to my newsletter
Read articles from Jalis Mahamud directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Jalis Mahamud
Jalis Mahamud
๐จโ๐ป Laravel Developer | PHP | MySQL | REST APIs Hi, I'm a Laravel developer with experience in building web applications using PHP and modern development practices. I work on backend systems, RESTful APIs, and database structures. I enjoy writing clean code, integrating third-party services, and improving workflows for better performance. ๐ง Tools I often use: Laravel, MySQL, Git, Composer, REST APIs ๐ Focused on: Simplicity, performance, and maintainability