FirebaseNotification   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 83
c 2
b 0
f 0
dl 0
loc 152
rs 10
wmc 15

6 Methods

Rating   Name   Duplication   Size   Complexity  
A sendToAll() 0 2 1
A getAccessToken() 0 9 1
A sendToTokens() 0 33 5
A subscribeToTopic() 0 28 3
A unsubscribeToTopic() 0 29 3
A sendToTopic() 0 27 2
1
<?php
2
3
namespace MedianetDev\CloudMessage\Drivers;
4
5
use Google\Client;
6
use MedianetDev\CloudMessage\Contracts\NotificationInterface;
7
use MedianetDev\CloudMessage\Jobs\MultiTokensJob;
8
9
class FirebaseNotification implements NotificationInterface
10
{
11
    use Notification;
12
13
    private static $firebaseApiBaseUrl = 'https://fcm.googleapis.com/v1/projects/';
14
    private static $firebaseMessagingScope = 'https://www.googleapis.com/auth/firebase.messaging';
15
    private static $googleApiBaseUrl = 'https://iid.googleapis.com/iid/v1/';
16
17
    public static function sendToAll(array $message)
18
    {
19
        // TODO: Send to all devices
20
    }
21
22
    public static function sendToTopic(array $message, $topic)
23
    {
24
        $headers = [
25
            'Authorization: Bearer ' . self::getAccessToken(),
26
            'Content-Type: application/json',
27
        ];
28
29
        $url = self::$firebaseApiBaseUrl . config('cloud_message.firebase.project_id') . '/messages:send';
30
31
        if (isset($message['data'])) {
32
            $message['data'] = json_encode($message['data'], JSON_UNESCAPED_UNICODE);
33
        }
34
35
        $data = [
36
            'message' => [
37
                'topic' => $topic,
38
                'data' => $message,
39
                'notification' => [
40
                    'title' => $message['title'],
41
                    'body' => $message['body'],
42
                ],
43
            ],
44
        ];
45
46
        $response = self::request($url, json_encode($data), $headers);
47
48
        return ['status' => $response['status']];
49
    }
50
51
    public static function sendToTokens(array $message, array $tokens)
52
    {
53
        $url = self::$firebaseApiBaseUrl . config('cloud_message.firebase.project_id') . '/messages:send';
54
        try {
55
            if (isset($message['data'])) {
56
                $message['data'] = json_encode($message['data'], JSON_UNESCAPED_UNICODE);
57
            }
58
59
            $headers = [
60
                'Authorization: Bearer ' . self::getAccessToken(),
61
                'Content-Type: application/json',
62
            ];
63
            if (config('cloud_message.async_requests')) {
64
                dispatch(new MultiTokensJob($tokens, $message, $url, $headers));
65
            } else {
66
                foreach ($tokens as $mobileId) {
67
                    self::request($url, json_encode(['message' => [
68
                        'token' => $mobileId,
69
                        'data' => $message,
70
                        'notification' => [
71
                            'title' => $message['title'],
72
                            'body' => $message['body'],
73
                        ],
74
                    ]]), $headers);
75
                }
76
            }
77
78
            return [
79
                'status' => true,
80
            ];
81
        } catch (\Throwable $th) {
82
            return [
83
                'status' => false,
84
            ];
85
        }
86
    }
87
88
    public static function subscribeToTopic(string $topic, array $tokens)
89
    {
90
        $url = self::$googleApiBaseUrl . ':batchAdd';
91
92
        $headers = [
93
            'Authorization: Bearer ' . self::getAccessToken(),
94
            'Content-Type: application/json',
95
            'access_token_auth: true',
96
        ];
97
98
        $success = true;
99
        $chunkedTokens = array_chunk($tokens, 500);
100
101
        foreach ($chunkedTokens as $tokenGroup) {
102
            $data = [
103
                'to' => '/topics/' . $topic,
104
                'registration_tokens' => $tokenGroup,
105
            ];
106
107
            $response = self::request($url, json_encode($data), $headers);
108
            $statusCode = $response['status'];
109
            if (200 != $statusCode) {
110
                $success = false;
111
            }
112
        }
113
114
        return [
115
            'status' => $success,
116
        ];
117
    }
118
119
    public static function unsubscribeToTopic(string $topic, array $tokens)
120
    {
121
        $url = self::$googleApiBaseUrl . ':batchRemove';
122
123
        $headers = [
124
            'Authorization: Bearer ' . self::getAccessToken(),
125
            'Content-Type: application/json',
126
            'access_token_auth: true',
127
        ];
128
129
        $success = true;
130
        $chunkedTokens = array_chunk($tokens, 500);
131
132
        foreach ($chunkedTokens as $tokenGroup) {
133
            $data = [
134
                'to' => '/topics/' . $topic,
135
                'registration_tokens' => $tokenGroup,
136
            ];
137
138
            $response = self::request($url, json_encode($data), $headers);
139
            $statusCode = $response['status'];
140
141
            if (200 != $statusCode) {
142
                $success = false;
143
            }
144
        }
145
146
        return [
147
            'status' => $success,
148
        ];
149
    }
150
151
    // Other required interface methods
152
    private static function getAccessToken()
153
    {
154
        $client = new Client();
155
        $client->setAuthConfig(config('cloud_message.firebase.path_to_service_account'));
156
        $client->addScope(self::$firebaseMessagingScope);
157
        $client->useApplicationDefaultCredentials();
158
        $token = $client->fetchAccessTokenWithAssertion();
159
160
        return $token['access_token'] ?? '';
161
    }
162
}
163