Completed
Push — master ( 0d4684...fff311 )
by Chris
01:24
created

FcmChannel   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 2
dl 0
loc 87
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
B send() 0 37 7
A sendToFcm() 0 8 2
A sendToFcmMulticast() 0 8 2
1
<?php
2
3
namespace NotificationChannels\Fcm;
4
5
use GuzzleHttp\Client;
6
use Illuminate\Notifications\Notification;
7
use Kreait\Firebase\Exception\MessagingException;
8
use Kreait\Firebase\Messaging\CloudMessage;
9
use Kreait\Firebase\Messaging\Message;
10
use Kreait\Laravel\Firebase\Facades\FirebaseMessaging;
11
use NotificationChannels\Fcm\Exceptions\CouldNotSendNotification;
12
13
class FcmChannel
14
{
15
    const MAX_TOKEN_PER_REQUEST = 500;
16
17
    /**
18
     * @var Client
19
     */
20
    protected $client;
21
22
    /**
23
     * Send the given notification.
24
     *
25
     * @param mixed $notifiable
26
     * @param Notification $notification
27
     *
28
     * @return array
29
     * @throws CouldNotSendNotification
30
     */
31
    public function send($notifiable, Notification $notification)
32
    {
33
        $token = $notifiable->routeNotificationFor('fcm');
34
35
        if (empty($token)) {
36
            throw new CouldNotSendNotification('No FCM token found for notifiable.');
37
        }
38
39
        // Get the message from the notification class
40
        $fcmMessage = $notification->toFcm($notifiable);
0 ignored issues
show
Bug introduced by
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...
41
42
        if (! $fcmMessage instanceof Message) {
43
            throw new CouldNotSendNotification('The toFcm() method only accepts instances of ' . Message::class);
44
        }
45
46
        $responses = [];
47
48
        if (! is_array($token)) {
49
            if ($fcmMessage instanceof CloudMessage) {
50
                $fcmMessage = $fcmMessage->withChangedTarget('token', $token);
51
            }
52
53
            if ($fcmMessage instanceof FcmMessage) {
54
                $fcmMessage->setToken($token);
55
            }
56
57
            $responses[] = $this->sendToFcm($fcmMessage);
58
        } else {
59
            // Use multicast because there are multiple recipients
60
            $partialTokens = array_chunk($token, self::MAX_TOKEN_PER_REQUEST, false);
61
            foreach ($partialTokens as $tokens) {
62
                $responses[] = $this->sendToFcmMulticast($fcmMessage, $tokens);
63
            }
64
        }
65
66
        return $responses;
67
    }
68
69
    /**
70
     * @param Message $fcmMessage
71
     *
72
     * @return mixed
73
     * @throws CouldNotSendNotification
74
     */
75
    protected function sendToFcm(Message $fcmMessage)
76
    {
77
        try {
78
            return FirebaseMessaging::send($fcmMessage);
79
        } catch (MessagingException $messagingException) {
80
            throw CouldNotSendNotification::serviceRespondedWithAnError($messagingException);
81
        }
82
    }
83
84
    /**
85
     * @param $fcmMessage
86
     * @param $tokens
87
     *
88
     * @return mixed
89
     * @throws CouldNotSendNotification
90
     */
91
    protected function sendToFcmMulticast($fcmMessage, $tokens)
92
    {
93
        try {
94
            return FirebaseMessaging::sendMulticast($fcmMessage, $tokens);
95
        } catch (MessagingException $messagingException) {
96
            throw CouldNotSendNotification::serviceRespondedWithAnError($messagingException);
97
        }
98
    }
99
}
100