From 33b7499a2edafb629b49ba0e71fef3c52af92d80 Mon Sep 17 00:00:00 2001 From: Fabio Ferrero Date: Tue, 25 Jun 2024 12:18:55 +0200 Subject: [PATCH 1/2] Add example with payload data --- README.md | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d110cee..ad12e7c 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,12 @@ php-fcm-v1 is an PHP implementation of [FCM](https://firebase.google.com/docs/cl ### What is different compared to others FCM Libraries? Most of other libraries are implementation of FCM's [Legacy HTTP Server Protocol](https://firebase.google.com/docs/cloud-messaging/http-server-ref). It requires a server key from Firebase console (which means you have to copy and paste in your code) ([Docs](https://firebase.google.com/docs/cloud-messaging/auth-server#authorize_legacy_protocol_send_requests)) -HTTP v1 API, in contrast, leverages OAuth2 security model. You need to get an access token (which is valid for about an hour) in order to request sending notification with service account's private key file. Although +HTTP v1 API, in contrast, leverages OAuth2 security model. You need to get an access token (which is valid for about an hour) in order to request sending notification with service account's private key file. Although (See the blog [post](https://firebase.googleblog.com/2017/11/whats-new-with-fcm-customizing-messages.html) about HTTP v1 API) ### References * [google/node-gtoken](https://github.com/google/node-gtoken) -* [google/google-auth-library-nodejs](https://github.com/google/google-auth-library-nodejs) +* [google/google-auth-library-nodejs](https://github.com/google/google-auth-library-nodejs) : Above two libraries let me understand how HTTP v1 API works in FCM * [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) : GuzzleHttp let this library to PSR7 compatible * [Paragraph1/php-fcm](https://github.com/Paragraph1/php-fcm) : Inspired me how FCM libraries are used in Legacy HTTP Protocol @@ -94,6 +94,35 @@ HTTP v1 API, in contrast, leverages OAuth2 security model. You need to get an ac $client -> fire(); ``` +* Example with payload data + + ```php + setPayload($bar); + + $recipient -> setSingleRecipient('DEVICE_TOKEN'); + $notification -> setNotification('NOTIFICATION_TITILE', 'NOTIFICATION_BODY'); + $client -> build($recipient, $notification, $payload); + $client -> fire(); + ``` + * Using with *PRIOIRTY* option (for both Android & iOS) ```php @@ -125,7 +154,7 @@ HTTP v1 API, in contrast, leverages OAuth2 security model. You need to get an ac $androidConfig = new Config\AndroidConfig(); $androidConfig -> setPriority(Config\AndroidConfig::PRIORITY_HIGH); $client -> build($recipient, $notification, null, $androidConfig); - + // Option Instance for iOS (which is APNs header) // Use phpFCMv1\APNsCOnfig Class $apnsConfig = new APNsConfig(); From 3bfbccdfee6a80bcfc85ab46e23ae207222d0363 Mon Sep 17 00:00:00 2001 From: Fabio Ferrero Date: Tue, 25 Jun 2024 12:19:17 +0200 Subject: [PATCH 2/2] Modified to store access token and reuse until expire --- src/Credentials.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Credentials.php b/src/Credentials.php index 5e06de5..1b5d1ca 100644 --- a/src/Credentials.php +++ b/src/Credentials.php @@ -25,6 +25,10 @@ class Credentials { private $keyFilePath; private $DATA_TYPE; + // Added to save access_token and use it until expire + private $access_token = ''; + private $expire = 0; + /** * Credentials constructor. Checks whether given path is a valid file. * @param string $keyFile @@ -46,14 +50,18 @@ public function getAccessToken() { 'grant_type' => self::GRANT_TYPE, 'assertion' => $this -> getTokenPayload() ); - - $result = $this -> getToken($requestBody); - - if (isset($result['error'])) { - throw new \RuntimeException($result['error_description']); + if ( strlen( $this->access_token ) == 0 || ( $this->expire <= time() ) ) { + $result = $this -> getToken($requestBody); + if (isset($result['error'])) { + $this->access_token = ''; + $this->expire = 0; + throw new \RuntimeException($result['error_description']); + } else { + $this->access_token = $result['access_token']; + $this->expire = time() + $result['expires_in']; + } } - - return $result['access_token']; + return $this->access_token; } /**