FirebaseNotification   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 84
c 2
b 0
f 0
dl 0
loc 155
rs 10
wmc 16

6 Methods

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