Laravel FCM Notification Channel

repository·master·Indexed 20 days ago

https://github.com/laravel-notification-channels/fcm

A notification channel for Laravel that enables sending push notifications via Firebase Cloud Messaging (FCM). It supports targeting specific device tokens, topics, or conditions, and integrates with the kreait/laravel-firebase library for authentication. The package provides FcmChannel for standard notifications, FcmTopicChannel for topic-based messaging, and a fluent FcmMessage interface for configuring payloads, including platform-specific options for Android and iOS.

Tokens
3.8K
Snippets
13
Records
15
Agent score
70%

What's inside laravel-notification-channels/fcm

  1. Handle FCM notification failures

    master

    When an FCM notification fails, Laravel dispatches the Illuminate\Notifications\Events\NotificationFailed event. You can listen for this event to perform cleanup tasks, such as deleting expired or invalid FCM tokens from your database.

    namespace App\
    Listeners;
    
    use Illuminate\Notifications\Events\NotificationFailed;
    use Illuminate\Support\Arr;
    
    class DeleteExpiredNotificationTokens
    {
        public function handle(NotificationFailed $event): void
        {
            if ($event->channel == \NotificationChannels\Fcm\FcmChannel::class) {
                $report = Arr::get($event->data, 'report');
                $target = $report->target();
    
                $event->notifiable->notificationTokens()
                    ->where('push_token', $target->value())
                    ->delete();
            }
        }
    }

    Register the listener in your EventServiceProvider:

    protected $listen = [
        \Illuminate\Notifications\Events\NotificationFailed::class => [
            \App\Listeners\DeleteExpiredNotificationTokens::class,
        ],
    ];
  2. Send FCM notifications via Notification classes

    master

    To send notifications to specific users, implement the toFcm method in your Notification class and return an FcmMessage. You must also define a routeNotificationForFcm() method on your Notifiable model to provide the device token(s).

    use Illuminate
    otifications\
    Notification;
    use NotificationChannels\Fcm\FcmChannel;
    use NotificationChannels\Fcm\FcmMessage;
    use NotificationChannels\Fcm\Resources\Notification as FcmNotification;
    
    class AccountActivated extends Notification
    {
        public function via($notifiable)
        {
            return [FcmChannel::class];
        }
    
        public function toFcm($notifiable): FcmMessage
        {
            return (new FcmMessage(notification: new FcmNotification(
                    title: 'Account Activated',
                    body: 'Your account has been activated.',
                    image: 'http://example.com/url-to-image-here.png'
                )))
                ->data(['data1' => 'value', 'data2' => 'value2'])
                ->custom([
                    'android' => [
                        'notification' => [
                            'color' => '#0A0A0A',
                            'sound' => 'default',
                        ],
                        'fcm_options' => [
                            'analytics_label' => 'analytics',
                        ],
                    ],
                    'apns' => [
                        'payload' => [
                            'aps' => [
                                'sound' => 'default'
                            ],
                        ],
                        'fcm_options' => [
                            'analytics_label' => 'analytics',
                        ],
                    ],
                ]);
        }
    }
    
    // In your User model:
    class User extends Authenticatable
    {
        use Notifiable;
    
        public function routeNotificationForFcm()
        {
            return $this->fcm_token; // Or return an array of tokens for multicast
        }
    }
    
    // To trigger:
    $user->notify(new AccountActivated);
  3. Send notifications to FCM topics

    master

    To send notifications to a topic instead of a specific device, use the FcmTopicChannel. You can route an on-demand notification to a topic name.

    use NotificationChannels\Fcm\FcmTopicChannel;
    
    Notification::route(FcmTopicChannel::class, 'news')
        ->notify(new BlogCreated($blog));
  4. Handle failed FCM notifications

    master

    When sending multicast notifications, if any individual delivery fails, the FcmChannel identifies the failure via the MulticastSendReport. It then dispatches a standard Laravel NotificationFailed event.

    You can listen for this event to perform cleanup, log errors, or retry deliveries. The event payload includes the report which contains the specific SendReport for the failed delivery.

  5. Use a custom Firebase Messaging client

    master

    If you need to override the default Firebase client, you can provide an instance of Kreait\Firebase\Contract\Messaging to the FcmMessage using the usingClient() method.

    public function toFcm(mixed $notifiable): FcmMessage
    {
        $client = app(\Kreait\Firebase\Contract\Messaging::class);
    
        return FcmMessage::create()->usingClient($client);
    }
  6. Configure FCM tokens in the Notifiable model

    master

    Your Notifiable model must implement routeNotificationForFcm() to tell the channel where to send the message. This method can return a single string (token) or an array of strings (for multicast/multiple devices).

    /**
     * Specifies the user's FCM token(s)
     *
     * @return string|array
     */
    public function routeNotificationForFcm()
    {
        return $this->fcm_token;
    }
  7. Available FcmMessage methods

    master

    The FcmMessage class provides a fluent interface to build the FCM payload. Key methods include:

    • name(string $name)
    • token(string $token)
    • topic(string $topic)
    • condition(string $condition)
    • data(array $data)
    • custom(array $custom)
    • usingClient(Kreait\Firebase\Contract\Messaging $client)
    FcmMessage::create()
        ->name('name')
        ->token('token')
        ->topic('topic')
        ->condition('condition')
        ->data(['a' => 'b'])
        ->custom(['notification' => []]);
  8. Construct and configure an FcmMessage

    master

    The FcmMessage class is used to build the payload for Firebase Cloud Messaging notifications. You can instantiate it via the constructor or the create() static method. It supports targeting via a specific device token, a topic, or a condition.

    Important Constraints:

    • Data Payload: When using the data() method, all values in the array must be strings. Providing non-string values will throw an InvalidArgumentException.
    • Targeting: You should typically provide either a token, a topic, or a condition to define the recipient(s).
    use NotificationChannels\Fcm\FcmMessage;
    use NotificationChannels\Fcm\Resources\Notification;
    
    $message = FcmMessage::create()
        ->token('DEVICE_TOKEN')
        ->notification(new Notification(title: 'Hello', body: 'World'))
        ->data(['key' => 'value']);
  9. Create an FCM notification payload with the Notification class

    master

    The NotificationChannels\Fcm\Resources\Notification class is used to construct the visual payload for an FCM message. It allows you to define the title, body, and an optional image URL. You can instantiate it via the constructor or use fluent setter methods. When converted to an array via toArray(), only the non-null fields are included in the payload.

    use NotificationChannels\Fcm\Resources\Notification;
    
    // Using the constructor
    $notification = new Notification(
        title: 'Hello World',
        body: 'This is a notification body',
        image: 'https://example.com/image.png'
    );
    
    // Or using fluent setters
    $notification = (new Notification())
        ->title('Hello World')
        ->body('This is a notification body')
        ->image('https://example.com/image.png');
  10. Send notifications to FCM topics using FcmTopicChannel

    master

    The FcmTopicChannel is a specialized channel used to send Firebase Cloud Messaging notifications to entire topics rather than individual device tokens.

    To use this channel, your notification class must implement a toFcm method that returns an FCM message object. The channel determines the target topic using one of two methods:

    1. From the Message object: If the message returned by toFcm($notifiable) has a topic explicitly set, that topic is used.
    2. From the Notifiable: If the message does not have a topic set, the channel attempts to resolve the topic via the $notifiable->routeNotificationFor('fcm-topic') method.

    If no topic is found in either location, the notification is not sent.

    <?php
    
    namespace App\Notifications;
    
    use NotificationChannels\Fcm\FcmMessage;
    use Illuminate
    otifications\Notification;
    
    class TopicNotification extends Notification
    {
        public function toFcm($notifiable): FcmMessage
        {
            return FcmMessage::create()
                ->setTopic('news')
                ->setData(['key' => 'value']);
        }
    }