Completed
Push — master ( eeb7ed...c2f085 )
by Atymic
01:10
created

FcmChannel::failedNotification()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
namespace NotificationChannels\Fcm;
4
5
use Illuminate\Contracts\Events\Dispatcher;
6
use Illuminate\Notifications\Events\NotificationFailed;
7
use Illuminate\Notifications\Notification;
8
use Kreait\Firebase\Exception\MessagingException;
9
use Kreait\Firebase\Messaging as MessagingClient;
10
use Kreait\Firebase\Messaging\CloudMessage;
11
use Kreait\Firebase\Messaging\Message;
12
use NotificationChannels\Fcm\Exceptions\CouldNotSendNotification;
13
use Throwable;
14
15
class FcmChannel
16
{
17
    const MAX_TOKEN_PER_REQUEST = 500;
18
19
    /**
20
     * @var MessagingClient
21
     */
22
    protected $client;
23
24
    /***
25
     * @var Dispatcher
26
     */
27
    protected $events;
28
29
    /**
30
     * FcmChannel constructor.
31
     *
32
     * @param MessagingClient $client
33
     * @param Dispatcher $dispatcher
34
     */
35
    public function __construct(MessagingClient $client, Dispatcher $dispatcher)
36
    {
37
        $this->client = $client;
38
        $this->events = $dispatcher;
39
    }
40
41
    /**
42
     * Send the given notification.
43
     *
44
     * @param mixed $notifiable
45
     * @param Notification $notification
46
     *
47
     * @return array
48
     * @throws CouldNotSendNotification|\Kreait\Firebase\Exception\FirebaseException
49
     */
50
    public function send($notifiable, Notification $notification)
51
    {
52
        $token = $notifiable->routeNotificationFor('fcm', $notification);
53
54
        if (empty($token)) {
55
            return [];
56
        }
57
58
        // Get the message from the notification class
59
        $fcmMessage = $notification->toFcm($notifiable);
0 ignored issues
show
Bug introduced by Chris Bautista
The method toFcm() does not seem to exist on object<Illuminate\Notifications\Notification>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
60
61
        if (! $fcmMessage instanceof Message) {
62
            throw CouldNotSendNotification::invalidMessage();
63
        }
64
65
        $responses = [];
66
67
        try {
68
            if (is_array($token)) {
69
                // Use multicast when there are multiple recipients
70
                $partialTokens = array_chunk($token, self::MAX_TOKEN_PER_REQUEST, false);
71
                foreach ($partialTokens as $tokens) {
72
                    $responses[] = $this->sendToFcmMulticast($fcmMessage, $tokens);
73
                }
74
            } else {
75
                $responses[] = $this->sendToFcm($fcmMessage, $token);
76
            }
77
        } catch (MessagingException $exception) {
78
            $this->failedNotification($notifiable, $notification, $exception);
79
            throw CouldNotSendNotification::serviceRespondedWithAnError($exception);
80
        }
81
82
        return $responses;
83
    }
84
85
    /**
86
     * @param Message $fcmMessage
87
     * @param $token
88
     * @return array
89
     * @throws MessagingException
90
     * @throws \Kreait\Firebase\Exception\FirebaseException
91
     */
92
    protected function sendToFcm(Message $fcmMessage, $token)
93
    {
94
        if ($fcmMessage instanceof CloudMessage) {
95
            $fcmMessage = $fcmMessage->withChangedTarget('token', $token);
96
        }
97
98
        if ($fcmMessage instanceof FcmMessage) {
99
            $fcmMessage->setToken($token);
100
        }
101
102
        return $this->client->send($fcmMessage);
103
    }
104
105
    /**
106
     * @param $fcmMessage
107
     * @param array $tokens
108
     * @return MessagingClient\MulticastSendReport
109
     * @throws MessagingException
110
     * @throws \Kreait\Firebase\Exception\FirebaseException
111
     */
112
    protected function sendToFcmMulticast($fcmMessage, array $tokens)
113
    {
114
        return $this->client->sendMulticast($fcmMessage, $tokens);
115
    }
116
117
    /**
118
     * Dispatch failed event.
119
     *
120
     * @param $notifiable
121
     * @param Notification $notification
122
     * @param Throwable $exception
123
     * @return array|null
124
     */
125
    protected function failedNotification($notifiable, Notification $notification, Throwable $exception)
126
    {
127
        return $this->events->dispatch(new NotificationFailed(
128
            $notifiable,
129
            $notification,
130
            self::class,
131
            [
132
                'message' => $exception->getMessage(),
133
                'exception' => $exception,
134
            ]
135
        ));
136
    }
137
}
138