Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

notification not sending to devices using in laravel using fcm by laravel-notification-channels/fcm #216

Closed
sameededitz opened this issue Jan 30, 2025 · 6 comments

Comments

@sameededitz
Copy link

im using it to send notifications to all my devices

im not linking it to any user bc i want to send notification to all devices

i have a table and model named
DeviceToken.php that stores all the devicetokens/fcm_tokens of devices

DeviceToken.php Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;

class DeviceToken extends Model
{
    use Notifiable;

    protected $fillable = ['fcm_token'];

    public static function getAllTokens(): array
    {
        return self::pluck('fcm_token')->toArray();
    }
}

now i have notification table and i want that whenever a new notification is created then that notification is sent to all devices not to any specific users/devices that have my app installed

so i did this

SendNotification.php Notification Class

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use NotificationChannels\Fcm\FcmChannel;
use NotificationChannels\Fcm\FcmMessage;
use NotificationChannels\Fcm\Resources\Notification as FcmNotification;

class SendNotification extends Notification
{
    public $title;
    public $body;

    /**
     * Create a new notification instance.
     */
    public function __construct($title, $body)
    {
        $this->title = $title;
        $this->body = $body;
    }

    public function via($notifiable)
    {
        return [FcmChannel::class];
    }

    /**
     * Get the mail representation of the notification.
     */
    public function toFcm($notifiable): FcmMessage
    {
        return (new FcmMessage(notification: new FcmNotification(
            title: $this->title,
            body: $this->body
        )))
            ->data(['data1' => 'value', 'data2' => 'value2'])  // Additional data
            ->custom([
                'android' => [
                    'notification' => [
                        'color' => '#0A0A0A',
                    ],
                ],
                'apns' => [
                    'fcm_options' => [
                        'analytics_label' => 'analytics',
                    ],
                ],
            ]);
    }
}

and thats my observer below which is called whenever a new notification record is created in db

NotificationObserver.php

<?php

namespace App\Observers;

use App\Models\DeviceToken;
use App\Models\Notification;
use App\Notifications\SendNotification;
use Illuminate\Contracts\Events\ShouldHandleEventsAfterCommit;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification as NotificationFacade;
use NotificationChannels\Fcm\FcmChannel;

class NotificationObserver implements ShouldHandleEventsAfterCommit
{
    /**
     * Handle the Notification "created" event.
     */
    public function created(Notification $notification): void
    {
        // Fetch all FCM tokens from the device_tokens table
        $deviceTokens = DeviceToken::getAllTokens();

        if (!empty($deviceTokens)) {
            // Send the notification via FCM
            try {
                // Optionally, chunk the tokens if you have many (e.g., 1000)
                $chunkSize = 500;
                $chunks = array_chunk($deviceTokens, $chunkSize);

                foreach ($chunks as $chunk) {
                    NotificationFacade::route(FcmChannel::class, $chunk)
                        ->notify(new SendNotification($notification->title, $notification->body));
                }

                Log::channel("notification")->info("Notification sent to " . count($deviceTokens) . " devices.");
            } catch (\Exception $e) {
                Log::channel("notification")->error("Error sending notification: " . $e->getMessage());
            }
        } else {
            Log::channel("notification")->warning("No device tokens found");
        }
    }
}

in logs i see this

[2025-01-30 15:41:25] local.INFO: Notification sent to 3 devices.  
[2025-01-30 15:42:14] local.INFO: Notification sent to 3 devices.  

no error seems here but not a single device recieve notification

also i tried doing this

dd(NotificationFacade::route(FcmChannel::class, $chunk)->notify(new SendNotification($notification->title, $notification->body)));

and it returns null and nothing more

please help me im stuck with it

@dwightwatson
Copy link
Collaborator

notify typically returns null.

If you can provide a reproduction in a Laravel app I can look into this further but otherwise I can't do much here.

@sameededitz
Copy link
Author

notify typically returns null.

If you can provide a reproduction in a Laravel app I can look into this further but otherwise I can't do much here.

how i can do so?

@dwightwatson
Copy link
Collaborator

Provide a fresh Laravel app that demonstrates the bug so I can pull it down and see the issue first hand. If I can't replicate the bug I can't help fix it.

@sameededitz
Copy link
Author

Provide a fresh Laravel app that demonstrates the bug so I can pull it down and see the issue first hand. If I can't replicate the bug I can't help fix it.

bro should i give you the repo link? in which im using this?

https://github.com/sameededitz/drivewise

i cant understand?

@sameededitz
Copy link
Author

Provide a fresh Laravel app that demonstrates the bug so I can pull it down and see the issue first hand. If I can't replicate the bug I can't help fix it.

can i contact u any other platform? so we can chat easily?

@dwightwatson
Copy link
Collaborator

Thanks - it looks like the issue only occurs with Anonymous notifiables as you're using here. It stems from this line in FcmChannel.

$tokens = Arr::wrap($notifiable->routeNotificationFor('fcm', $notification));

Generally this will call the routeNotificationForFcm() method on the notifiable, but it doesn't work like that on the anonymous notifiable.

I think the fix for your use case is to update your routing to use fcm instead of the whole channel name.

foreach ($chunks as $chunk) {
    NotificationFacade::route('fcm', $chunk)
        ->notify(new SendNotification('hello', 'world'));
}

I'm not sure if there is a more conventional way for us to deal with this on the package side. However, this means your notification will be receiving tokens (where previously it was always getting an empty array).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants