Skip to content

Commit 59d22d1

Browse files
committed
Support HTTP V1. Only Device Messages. Topics still not supported.
1 parent e7e63fb commit 59d22d1

16 files changed

+211
-742
lines changed

.php-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
8.3

README.md

+11-11
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ Or add this to your composer.json and run "composer update":
2525

2626
# Send message to **one or multiple** Devices
2727
```
28-
use sngrl\PhpFirebaseCloudMessaging\Client;
29-
use sngrl\PhpFirebaseCloudMessaging\Message;
30-
use sngrl\PhpFirebaseCloudMessaging\Recipient\Device;
31-
use sngrl\PhpFirebaseCloudMessaging\Notification;
28+
use RedjanYm\FCM\Client;
29+
use RedjanYm\FCM\Message;
30+
use RedjanYm\FCM\Recipient\Device;
31+
use RedjanYm\FCM\Notification;
3232
3333
$server_key = '_YOUR_SERVER_KEY_';
3434
$client = new Client();
@@ -51,10 +51,10 @@ var_dump($response->getBody()->getContents());
5151
Currently sending to topics only supports a single topic as recipient. Mutliple topic as outlined
5252
in the google docs don't seem to work, yet.
5353
```
54-
use sngrl\PhpFirebaseCloudMessaging\Client;
55-
use sngrl\PhpFirebaseCloudMessaging\Message;
56-
use sngrl\PhpFirebaseCloudMessaging\Recipient\Topic;
57-
use sngrl\PhpFirebaseCloudMessaging\Notification;
54+
use RedjanYm\FCM\Client;
55+
use RedjanYm\FCM\Message;
56+
use RedjanYm\FCM\Recipient\Topic;
57+
use RedjanYm\FCM\Notification;
5858
5959
$server_key = '_YOUR_SERVER_KEY_';
6060
$client = new Client();
@@ -75,7 +75,7 @@ var_dump($response->getBody()->getContents());
7575

7676
# Subscribe user to the topic
7777
```
78-
use sngrl\PhpFirebaseCloudMessaging\Client;
78+
use RedjanYm\FCM\Client;
7979
8080
$server_key = '_YOUR_SERVER_KEY_';
8181
$client = new Client();
@@ -88,7 +88,7 @@ var_dump($response->getBody()->getContents());
8888

8989
# Remove user subscription to the topic
9090
```
91-
use sngrl\PhpFirebaseCloudMessaging\Client;
91+
use RedjanYm\FCM\Client;
9292
9393
$server_key = '_YOUR_SERVER_KEY_';
9494
$client = new Client();
@@ -102,4 +102,4 @@ var_dump($response->getBody()->getContents());
102102
# Interpreting responses
103103
Responses given on the HTTP requests are standard according to the FCM documentations. You may find detailed specifications in this links:
104104
* https://firebase.google.com/docs/cloud-messaging/http-server-ref#interpret-downstream
105-
* https://firebase.google.com/docs/cloud-messaging/http-server-ref#error-codes
105+
* https://firebase.google.com/docs/cloud-messaging/http-server-ref#error-codes

composer.json

+6-18
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,23 @@
11
{
22
"name": "redjanym/php-firebase-cloud-messaging",
3-
"description": "PHP API for Firebase Cloud Messaging from Google",
3+
"description": "PHP SDK for Firebase Cloud Messaging from Google",
44
"license": "MIT",
5-
"keywords": ["PHP","FCM","Google","Firebase","Cloud","Notifications","Android","iOS","Chrome"],
5+
"keywords": ["PHP","FCM","Google","Firebase","Cloud","Notifications","Android","iOS"],
66
"homepage": "https://github.com/redjanym/php-firebase-cloud-messaging",
77
"authors": [
8-
{
9-
"name": "Sngrl",
10-
"email": "[email protected]"
11-
},
128
{
139
"name": "Redjan Ymeraj",
14-
"email": "ymerajr@yahoo.com"
10+
"email": "ymerajredjan@gmail.com"
1511
}
1612
],
1713
"require": {
1814
"guzzlehttp/guzzle": "*",
19-
"php": ">=5.5"
20-
},
21-
"require-dev": {
22-
"phpunit/phpunit": "*",
23-
"mockery/mockery" : "*"
15+
"php": ">=7.4",
16+
"google/apiclient": "^2.18"
2417
},
2518
"autoload": {
2619
"psr-4": {
27-
"sngrl\\PhpFirebaseCloudMessaging\\": "src/"
28-
}
29-
},
30-
"autoload-dev": {
31-
"psr-4": {
32-
"sngrl\\PhpFirebaseCloudMessaging\\Tests\\": "tests/"
20+
"RedjanYm\\FCM\\": "src/"
3321
}
3422
}
3523
}

phpunit.xml.dist

-17
This file was deleted.

src/Client.php

+34-89
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,75 @@
11
<?php
2-
namespace sngrl\PhpFirebaseCloudMessaging;
2+
3+
namespace RedjanYm\FCM;
34

45
use GuzzleHttp;
6+
use Psr\Http\Message\ResponseInterface;
57

6-
/**
7-
* @author sngrl
8-
*/
98
class Client implements ClientInterface
109
{
11-
const DEFAULT_API_URL = 'https://fcm.googleapis.com/fcm/send';
12-
const DEFAULT_TOPIC_ADD_SUBSCRIPTION_API_URL = 'https://iid.googleapis.com/iid/v1:batchAdd';
13-
const DEFAULT_TOPIC_REMOVE_SUBSCRIPTION_API_URL = 'https://iid.googleapis.com/iid/v1:batchRemove';
14-
15-
private $apiKey;
16-
private $proxyApiUrl;
17-
private $guzzleClient;
10+
const DEFAULT_API_URL = 'https://fcm.googleapis.com/v1/projects/{PROJECT_ID}/messages:send';
11+
private string $projectId;
12+
private string $serviceAccountPath;
13+
private string $accessToken;
14+
private GuzzleHttp\Client $guzzleClient;
1815

19-
public function __construct()
16+
public function __construct(string $serviceAccountPath)
2017
{
18+
if (file_exists($serviceAccountPath) === false) {
19+
throw new \InvalidArgumentException('Service account file does not exist!');
20+
}
2121

22+
$this->serviceAccountPath = $serviceAccountPath;
2223
$this->guzzleClient = new \GuzzleHttp\Client();
2324
}
2425

25-
/**
26-
* add your server api key here
27-
* read how to obtain an api key here: https://firebase.google.com/docs/server/setup#prerequisites
28-
*
29-
* @param string $apiKey
30-
*
31-
* @return \sngrl\PhpFirebaseCloudMessaging\Client
32-
*/
33-
public function setApiKey($apiKey)
26+
public function setServiceAccountPath(string $serviceAccountPath): self
3427
{
35-
$this->apiKey = $apiKey;
36-
return $this;
37-
}
28+
$this->serviceAccountPath = $serviceAccountPath;
3829

39-
/**
40-
* people can overwrite the api url with a proxy server url of their own
41-
*
42-
* @param string $url
43-
*
44-
* @return \sngrl\PhpFirebaseCloudMessaging\Client
45-
*/
46-
public function setProxyApiUrl($url)
47-
{
48-
$this->proxyApiUrl = $url;
4930
return $this;
5031
}
5132

52-
/**
53-
* sends your notification to the google servers and returns a guzzle repsonse object
54-
* containing their answer.
55-
*
56-
* @param Message $message
57-
*
58-
* @return \Psr\Http\Message\ResponseInterface
59-
* @throws \GuzzleHttp\Exception\RequestException
60-
*/
61-
public function send(Message $message)
33+
public function applyCredentials(): self
6234
{
63-
return $this->guzzleClient->post(
64-
$this->getApiUrl(),
65-
[
66-
'headers' => [
67-
'Authorization' => sprintf('key=%s', $this->apiKey),
68-
'Content-Type' => 'application/json'
69-
],
70-
'body' => json_encode($message)
71-
]
72-
);
73-
}
35+
$this->projectId = \json_decode(file_get_contents($this->serviceAccountPath), true)['project_id'];
36+
$this->accessToken = $this->getAccessToken();
7437

75-
/**
76-
* @param integer $topic_id
77-
* @param array|string $recipients_tokens
78-
*
79-
* @return \Psr\Http\Message\ResponseInterface
80-
*/
81-
public function addTopicSubscription($topic_id, $recipients_tokens)
82-
{
83-
return $this->processTopicSubscription($topic_id, $recipients_tokens, self::DEFAULT_TOPIC_ADD_SUBSCRIPTION_API_URL);
38+
return $this;
8439
}
8540

86-
87-
/**
88-
* @param integer $topic_id
89-
* @param array|string $recipients_tokens
90-
*
91-
* @return \Psr\Http\Message\ResponseInterface
92-
*/
93-
public function removeTopicSubscription($topic_id, $recipients_tokens)
41+
private function getAccessToken(): string
9442
{
95-
return $this->processTopicSubscription($topic_id, $recipients_tokens, self::DEFAULT_TOPIC_REMOVE_SUBSCRIPTION_API_URL);
96-
}
43+
$client = new \Google\Client();
44+
$client->setAuthConfig($this->serviceAccountPath);
45+
$client->addScope('https://www.googleapis.com/auth/firebase.messaging');
46+
$client->useApplicationDefaultCredentials();
47+
$token = $client->fetchAccessTokenWithAssertion();
9748

49+
return $token['access_token'];
50+
}
9851

9952
/**
100-
* @param integer $topic_id
101-
* @param array|string $recipients_tokens
102-
* @param string $url
103-
*
104-
* @return \Psr\Http\Message\ResponseInterface
53+
* @throws \GuzzleHttp\Exception\RequestException
10554
*/
106-
protected function processTopicSubscription($topic_id, $recipients_tokens, $url)
55+
public function send(Message $message): ResponseInterface
10756
{
108-
if (!is_array($recipients_tokens))
109-
$recipients_tokens = [$recipients_tokens];
110-
11157
return $this->guzzleClient->post(
112-
$url,
58+
$this->getApiUrl(),
11359
[
11460
'headers' => [
115-
'Authorization' => sprintf('key=%s', $this->apiKey),
61+
'Authorization' => sprintf('Bearer %s', $this->accessToken),
11662
'Content-Type' => 'application/json'
11763
],
118-
'body' => json_encode([
119-
'to' => '/topics/' . $topic_id,
120-
'registration_tokens' => $recipients_tokens,
64+
'body' => \json_encode([
65+
'message' => $message,
12166
])
12267
]
12368
);
12469
}
12570

12671
private function getApiUrl()
12772
{
128-
return isset($this->proxyApiUrl) ? $this->proxyApiUrl : self::DEFAULT_API_URL;
73+
return str_replace('{PROJECT_ID}', $this->projectId, self::DEFAULT_API_URL);
12974
}
13075
}

src/ClientInterface.php

+7-36
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,14 @@
11
<?php
2-
namespace sngrl\PhpFirebaseCloudMessaging;
32

4-
/**
5-
*
6-
* @author sngrl
7-
*
8-
*/
3+
namespace RedjanYm\FCM;
4+
5+
use Psr\Http\Message\ResponseInterface;
6+
97
interface ClientInterface
108
{
9+
public function setServiceAccountPath(string $serviceAccountPath): self;
1110

12-
/**
13-
* add your server api key here
14-
* read how to obtain an api key here: https://firebase.google.com/docs/server/setup#prerequisites
15-
*
16-
* @param string $apiKey
17-
*
18-
* @return \sngrl\PhpFirebaseCloudMessaging\Client
19-
*/
20-
public function setApiKey($apiKey);
21-
22-
23-
/**
24-
* people can overwrite the api url with a proxy server url of their own
25-
*
26-
* @param string $url
27-
*
28-
* @return \sngrl\PhpFirebaseCloudMessaging\Client
29-
*/
30-
public function setProxyApiUrl($url);
11+
public function send(Message $message): ResponseInterface;
3112

32-
/**
33-
* sends your notification to the google servers and returns a guzzle repsonse object
34-
* containing their answer.
35-
*
36-
* @param Message $message
37-
*
38-
* @return \Psr\Http\Message\ResponseInterface
39-
* @throws \GuzzleHttp\Exception\RequestException
40-
*/
41-
public function send(Message $message);
42-
13+
public function applyCredentials(): self;
4314
}

0 commit comments

Comments
 (0)