sv1ft / laravel-fcm
A powerful Laravel package to send Push Notifications
Installs: 443
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 10
pkg:composer/sv1ft/laravel-fcm
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^6.2 || ^7.0
- illuminate/notifications: ~5.6 || ~6.0 || ~7.0 || ~8.0 || ~9.0 || ~10.0
- illuminate/support: ~5.6 || ~6.0 || ~7.0 || ~8.0 || ~9.0 || ~10.0
- kreait/laravel-firebase: ^5.0
- spatie/enum: ^2.3 || ^3.0
README
laravel-fcm is a powerful Laravel package to send Push Notifications to all devices of one or many users. Being channel-based you only need to specify the channel in your Laravel Notification.
Features
- Easy integration
- Compatible with any version of Laravel
- Send notifications to all devices of one or many users at the same time
- Send millions of notifications in batch
- Fully customizable and adaptable
- Queue support
📄 Content
💿 Installation
composer require williamcruzme/laravel-fcm
1. Configure the enviroment
Get the Service Account and paste in your .env file:
(gear-next-to-project-name) > Project Settings > Cloud Messaging
FIREBASE_CREDENTIALS=/path/to/service-account.json
2. Adding traits
In your App\Models\User model add the HasDevices trait:
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Williamcruzme\Fcm\HasDevices; class User extends Authenticatable { use Notifiable, HasDevices; }
Remember, you are not limited to only including the trait on your
App\Models\Usermodel.
3. Running migrations
php artisan migrate
(Optional) Sometimes you may need to customize the migrations. Using the vendor:publish command you can export the migrations:
php artisan vendor:publish --tag=migrations
4. Adding routes
In your routes/api.php add the routes using the Device facade, this is for manage the devices:
Route::middleware('auth')->group(function () { Device::routes(); });
⚡ Create notification
1. Creating notifications
php artisan make:notification InvoicePaid
2. Adding delivery channels
Every notification class has a via method that determines on which channels the notification will be delivered. Add fcm as delivery channel:
/** * Get the notification's delivery channels. * * @param mixed $notifiable * @return array */ public function via($notifiable) { return ['fcm']; }
3. Formatting notifications
The notification method support the Firebase payload:
/** * Get the Firebase Message representation of the notification. * * @param mixed $notifiable * @return \Williamcruzme\Fcm\Messages\FcmMessage */ public function toFcm($notifiable) { return (new FcmMessage) ->notification([ 'title' => 'Happy Code!', 'body' => 'This is a test', ]); }
4. Sending notifications
FcmMessage automatically gets all devices of the notifiable entities; you just need to send notifications. Notifications may be sent in two ways: using the notify method of the Notifiable trait or using the Notification facade. First, let's explore using the trait:
Using The Notifiable Trait
This trait is utilized by the default App\User model and contains one method that may be used to send notifications: notify. The notify method expects to receive a notification instance:
use App\Notifications\InvoicePaid; $user->notify(new InvoicePaid($invoice));
Remember, you may use the
Illuminate\Notifications\Notifiabletrait on any of your models. You are not limited to only including it on yourApp\Usermodel.
Using The Notification Facade
Alternatively, you may send notifications via the Notification facade. This is useful primarily when you need to send a notification to multiple notifiable entities such as a collection of users. To send notifications using the facade, pass all of the notifiable entities and the notification instance to the send method:
use App\Notifications\InvoicePaid; use Illuminate\Support\Facades\Notification; Notification::send($users, new InvoicePaid($invoice));
🌐 Routes
These routes are generated automatically, once wherever you add Device::routes();
Add device
| Method | URI |
|---|---|
| POST | /devices |
Body Params
{
"token": "fxssWy2Lgtk:APA91bFXy79AmofgTnBm5CfBpyeEFJsSHq0Xcdk..."
}
Remove device
| Method | URI |
|---|---|
| DELETE | /devices |
Body Params
{
"token": "fxssWy2Lgtk:APA91bFXy79AmofgTnBm5CfBpyeEFJsSHq0Xcdk..."
}
🎨 Customizing The Notification
Sending data
Using the data method you can specify the custom key-value pairs of the notification payload:
/** * Get the Firebase Message representation of the notification. * * @param mixed $notifiable * @return \Williamcruzme\Fcm\Messages\FcmMessage */ public function toFcm($notifiable) { return (new FcmMessage) ->notification([ 'title' => 'Happy Code!', 'body' => 'This is a test', ]) ->data([ 'type' => 'banner', 'link' => 'https://github.com/', ]); }
Adding conditions
Using the condition method you can specify a boolean expression to send the notification:
/** * Get the Firebase Message representation of the notification. * * @param mixed $notifiable * @return \Williamcruzme\Fcm\Messages\FcmMessage */ public function toFcm($notifiable) { return (new FcmMessage) ->condition("'stock-GOOG' in topics || 'industry-tech' in topics") ->notification([ 'title' => 'Happy Code!', 'body' => 'This is a test', ]); }
Setting priority
Using the priority method you can specify a priority of the notification. Default is normal:
/** * Get the Firebase Message representation of the notification. * * @param mixed $notifiable * @return \Williamcruzme\Fcm\Messages\FcmMessage */ public function toFcm($notifiable) { return (new FcmMessage) ->priority('high') ->notification([ 'title' => 'Happy Code!', 'body' => 'This is a test', ]); }
Custom payload
Using the payload method you can specify a custom payload to the notification:
/** * Get the Firebase Message representation of the notification. * * @param mixed $notifiable * @return \Williamcruzme\Fcm\Messages\FcmMessage */ public function toFcm($notifiable) { return (new FcmMessage) ->notification([ 'title' => 'Happy Code!', 'body' => 'This is a test', ]) ->payload([ 'android_channel_id' => '500' ]); }
🎨 Customizing The Controller
First of all, create your own DeviceController controller and add the ManageDevices trait.
Second, modify the namespace of the Device facade routes to :
Device::routes('App\Http\Controllers');
Custom request validations
The createRules deleteRules validationErrorMessages methods in the DeviceController allows you override the default request validations:
<?php namespace App\Http\Controllers; use Williamcruzme\Fcm\Traits\ManageDevices; class DeviceController extends Controller { use ManageDevices; /** * Get the validation rules that apply to the create a device. * * @return array */ protected function createRules() { return [ 'token' => ['required', 'string'], ]; } /** * Get the validation rules that apply to the delete a device. * * @return array */ protected function deleteRules() { return [ 'token' => ['required', 'string', 'exists:devices,token'], ]; } /** * Get the device management validation error messages. * * @return array */ protected function validationErrorMessages() { return []; } }
Custom response
The sendResponse and sendDestroyResponse method in the DeviceController allows you override the default response:
<?php namespace App\Http\Controllers; use Williamcruzme\Fcm\Traits\ManageDevices; class DeviceController extends Controller { use ManageDevices; /** * Get the response for a successful storing device. * * @param Williamcruzme\Fcm\Device $model * @return \Illuminate\Http\JsonResponse */ protected function sendResponse($model) { return response()->json($model); } /** * Get the response for a successful deleting device. * * @param Williamcruzme\Fcm\Device $model * @return \Illuminate\Http\JsonResponse */ protected function sendDestroyResponse($model) { return response()->json('', 204); } }
Custom guards
The guard method in the DeviceController allows you override the default guard:
<?php namespace App\Http\Controllers; use Williamcruzme\Fcm\Traits\ManageDevices; class DeviceController extends Controller { use ManageDevices; /** * Get the guard to be used during device management. * * @return \Illuminate\Contracts\Auth\StatefulGuard */ protected function guard() { return auth('admin')->guard(); } }
🚸 Contributing
You are welcome to contribute to this project, but before you do, please make sure you read the contribution guide.
🔒 License
MIT