diff --git a/src/FcmChannel.php b/src/FcmChannel.php index b0d667d..e828ef7 100644 --- a/src/FcmChannel.php +++ b/src/FcmChannel.php @@ -4,6 +4,8 @@ use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Notifications\Events\NotificationFailed; +use Illuminate\Notifications\Events\NotificationSending; +use Illuminate\Notifications\Events\NotificationSent; use Illuminate\Notifications\Notification; use Illuminate\Support\Arr; use Illuminate\Support\Collection; @@ -35,37 +37,40 @@ public function send(mixed $notifiable, Notification $notification): ?Collection { $tokens = Arr::wrap($notifiable->routeNotificationFor('fcm', $notification)); - if (empty($tokens)) { - return null; - } - - $fcmMessage = $notification->toFcm($notifiable); - return Collection::make($tokens) ->chunk(self::TOKENS_PER_REQUEST) - ->map(fn ($tokens) => ($fcmMessage->client ?? $this->client)->sendMulticast($fcmMessage, $tokens->all())) - ->map(fn (MulticastSendReport $report) => $this->checkReportForFailures($notifiable, $notification, $report)); + ->map(fn ($tokens) => $this->sendNotifications($notifiable, $notification, $tokens)) + ->map(fn (MulticastSendReport $report) => $this->dispatchEvents($notifiable, $notification, $report)); } /** - * Handle the report for the notification and dispatch any failed notifications. + * Send the notification with the provided tokens. */ - protected function checkReportForFailures(mixed $notifiable, Notification $notification, MulticastSendReport $report): MulticastSendReport + protected function sendNotifications(mixed $notifiable, Notification $notification, Collection $tokens): MulticastSendReport { - Collection::make($report->getItems()) - ->filter(fn (SendReport $report) => $report->isFailure()) - ->each(fn (SendReport $report) => $this->dispatchFailedNotification($notifiable, $notification, $report)); + $fcmMessage = $notification->toFcm($notifiable); - return $report; + $this->events->dispatch( + new NotificationSending($notifiable, $notification, self::class) + ); + + return ($fcmMessage->client ?? $this->client)->sendMulticast($fcmMessage, $tokens->all()); } /** - * Dispatch failed event. + * Handle the report for the notification and dispatch any failed notifications. */ - protected function dispatchFailedNotification(mixed $notifiable, Notification $notification, SendReport $report): void + protected function dispatchEvents(mixed $notifiable, Notification $notification, MulticastSendReport $report): MulticastSendReport { - $this->events->dispatch(new NotificationFailed($notifiable, $notification, self::class, [ - 'report' => $report, - ])); + Collection::make($report->getItems()) + ->each(function (SendReport $report) use ($notifiable, $notification) { + $event = $report->isSuccess() + ? new NotificationSent($notifiable, $notification, self::class, compact('report')) + : new NotificationFailed($notifiable, $notification, self::class, compact('report')); + + $this->events->dispatch($event); + }); + + return $report; } } diff --git a/tests/FcmChannelTest.php b/tests/FcmChannelTest.php index 132262e..868d574 100644 --- a/tests/FcmChannelTest.php +++ b/tests/FcmChannelTest.php @@ -4,6 +4,9 @@ use Exception; use Illuminate\Contracts\Events\Dispatcher; +use Illuminate\Notifications\Events\NotificationFailed; +use Illuminate\Notifications\Events\NotificationSending; +use Illuminate\Notifications\Events\NotificationSent; use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notification; use Illuminate\Support\Collection; @@ -36,7 +39,14 @@ public function test_it_can_be_instantiated() public function test_it_can_send_notifications() { $events = Mockery::mock(Dispatcher::class); - $events->shouldNotReceive('dispatch'); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSending::class)); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSent::class)); + $events->shouldNotReceive('dispatch') + ->with(Mockery::type(NotificationFailed::class)); $firebase = Mockery::mock(Messaging::class); $firebase->shouldReceive('sendMulticast') @@ -56,7 +66,14 @@ public function test_it_can_send_notifications() public function test_it_can_send_notifications_with_custom_client() { $events = Mockery::mock(Dispatcher::class); - $events->shouldNotReceive('dispatch'); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSending::class)); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSent::class)); + $events->shouldNotReceive('dispatch') + ->with(Mockery::type(NotificationFailed::class)); $firebase = Mockery::mock(Messaging::class); $events->shouldNotReceive('sendMulticast'); @@ -78,7 +95,14 @@ public function test_it_can_send_notifications_with_custom_client() public function test_it_can_dispatch_events() { $events = Mockery::mock(Dispatcher::class); - $events->shouldReceive('dispatch')->once(); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSending::class)); + $events->shouldNotReceive('dispatch') + ->with(Mockery::type(NotificationSent::class)); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationFailed::class)); $firebase = Mockery::mock(Messaging::class); $firebase->shouldReceive('sendMulticast')