PHP-FCM Documentation¶
PHP-FCM is a PHP HTTP client that makes it easy to send push notifications, manage groups of devices and message topics using Google Firebase Cloud Messaging.
<?php
// Load composer
require 'vendor/autoload.php';
// Instantiate the client with the project api_token and sender_id.
$client = new \Fcm\FcmClient($apiToken, $senderId);
// Instantiate the push notification request object.
$notification = new \Fcm\Push\Notification();
// Enhance the notification object with our custom options.
$notification
->addRecipient($deviceId)
->setTitle('Hello from php-fcm!')
->setBody('Notification body')
->setColor('#20F037')
->setSound("default")
->setIcon("myIcon.png")
->addData('key', 'value');
// custom sound and custom icon must be in app package
// - custom sound file must be in /res/raw/
// - custom icon file must be in drawable resource, if not set, FCM displays launcher icon in app manifest
// Send the notification to the Firebase servers for further handling.
$client->send($notification);
Before installing, read the Overview for more information about this project. Read the Quickstart for installation and using the project.
Overview¶
Requirements¶
- PHP 7.0
- A free Firebase account, read the Quickstart for more information.
Running the tests¶
This project uses PHPUnit for running its unit tests. Run the tests using the vendor provided phpunit binary:
vendor/bin/phpunit -c phpunit.dist.xml
License¶
Licensed using the MIT license.
Copyright (c) 2018 Edwin Hoksberg <https://github.com/Edwinhoksberg>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Quickstart¶
Installing this package¶
This package is available on packagist, and can be installed with composer:
composer require edwinhoksberg/php-fcm
Configuring a Firebase account¶
This project uses Google Firebase for sending notifications, so we need to signup for a free account. A free account can store up to ~20 million messages, device groups and topics.
- Click here to go the firebase console page.
- Click on the Create Project button. Enter a project name and select your country/region.
- Once your project is created, click on continue to go to the project dashboard.
- Click on the gear icon in the top left, next to the Project Overview link, and click on Project Settings.
- Go to the Cloud Messaging tab.
- On this page, you should see several authentication tokens. Copy and save the Server key and Sender ID tokens somewhere. These will be used in the project configuration.
Configuring the project¶
When you instantiate a new Firebase Cloud Messaging object, pass the Server Key and Sender ID you retrieved from the previous steps:
<?php
// Load composer
require 'vendor/autoload.php';
$client = new \Fcm\FcmClient(/* Server Key */, /* Sender ID */);
App integration¶
Android Integration¶
The easiest way to start is using the offcial example messaging app which can be found here. It is also documented on how to register a device and how to capture the device id, which will be used for sending notifications or managing device groups/topics.
Official documentation: https://firebase.google.com/docs/cloud-messaging/android/client.
iOS Integration¶
An example application was also made available for iOS, which can be found on the official github repository.
Official documentation: https://firebase.google.com/docs/cloud-messaging/ios/client.
Device Information¶
There is only 1 device call Firebase exposes, and it can be used to retrieve information about a single device, such as registration date and subscribed topics.
Device Info¶
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
// Remove the second parameter for more basic device information
$info = new \Fcm\Device\Info($deviceId, true);
// Shortcut function:
// $info = $client->deviceInfo($deviceId, true);
$client->send($info);
Example response:
array(10) {
'applicationVersion' =>
string(1) "1"
'connectDate' =>
string(10) "2018-08-07"
'attestStatus' =>
string(6) "ROOTED"
'application' =>
string(27) "com.google.application"
'scope' =>
string(1) "*"
'authorizedEntity' =>
string(12) "347372151029"
'rel' =>
array(1) {
'topics' =>
array(1) {
'news' =>
array(1) {
'addDate' =>
string(10) "2018-08-07"
}
}
}
'connectionType' =>
string(4) "WIFI"
'appSigner' =>
string(40) "c5abd4420a7b4844c034fe9c47fcb42234bbf5fe"
'platform' =>
string(7) "ANDROID"
}
Quirks¶
This plugin uses the underlying package guzzlehttp - this package is designed to error out if a URL/Link returns a 404 Not Found. However, this can cause the above DeviceInfo to error out at as well. When looking up a deviceID via FCM, if the deviceID does not exist the Google FCM API returns a 404 Not Found with the JSON value {“error”:”No information found about this instance id.”}. The 404 causes guzzlehttp to throw a Fatal Error and exit the script. Obviously, this is a major issue if you are scripting mass deviceID lookups - the first not found ID will exit your script.
To get around this, you can use the http_errors option, see Package Options.
Additionally, once the above modification is applied, you will need your processing script to check for JSON key error to process the proper error message. IE:
$info = new \Fcm\Device\Info($deviceID, true);
$response = $client->send($info);
if (array_key_exists('error',$response)) {
// process error info here
} else if (array_key_exists('rel',$response)) {
// process returned info here
} else {
// ID exists but is not registered to any topics/groups/etc
}
Sending Messages¶
There are two different types of messages Firebase can support, Notification messages and Data messages. Read here for more information.
Notification message to deviceIDs <to> <registration_ids> <deviceGroupID>¶
FCM automatically displays the message to end-user devices on behalf of the client app. Notification messages have a predefined set of user-visible keys and an optional data payload of custom key-value pairs.
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
$notification = new \Fcm\Push\Notification();
$notification
->addRecipient($deviceId1)
->addRecipient($deviceGroupID)
->addRecipient($arrayIDs)
->setTitle('Hello from php-fcm!')
->setColor('#20F037')
->setSound("default")
->setBadge(11)
->addData("key","value");
// Shortcut function:
// $notification = $client->pushNotification('The title', 'The body', $deviceId);
$response = $client->send($notification);
Example deviceID <to> <registration_ids> <deviceGroupID> response:
array(5) {
'multicast_id' =>
int(9014353506250345342)
'success' =>
int(1) // how many deviceIDs were successfully sent messages
'failure' =>
int(1) // how many deviceIDs messages failed to send to
'canonical_ids' =>
int(0)
'results' =>
array(2) {
[0] => // each deviceID message success or failure
array(1) {
'message_id' => //first ID success
string(35) "0:154231004164960%c5f39c08c5f39c543"
}
[1] => // each deviceID message success or failure
array(1) {
'error' => // second ID failure
string(19) "InvalidRegistration"
}
}
}
Notification message <topics>¶
FCM automatically displays the message to end-user devices on behalf of the client app. Notification messages have a predefined set of user-visible keys and an optional data payload of custom key-value pairs.
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
$notification = new \Fcm\Push\Notification();
$notification
->addRecipient('/topics/myTopicName')
->setTitle('Hello myTopicName Members')
->setColor('#20F037')
->setSound("default")
->setIcon("myIcon.png")
->addDataArray($myObjArray);
// Shortcut function:
// $notification = $client->pushNotification('The title', 'The body', $deviceId);
$response = $client->send($notification);
Example <topics> response:
array(1) {
'message_id' => // this is a successful response to a topic notification
int(154231004164960%c5f39c08c5f39c543)
}
array(1) {
'error' => // this is an error response to a topic notification
string(19) "InvalidRegistration"
}
Notification sending options¶
* addRecipient
// recipient can be ONE of four types
// deviceID (string)
// devicegroupID (string)
// registeredIDs (array_of_IDs)
// topicID ('/topics/myTopicID')
// note: deviceID/deviceGroupID/registerIDs can be mixed/matched in same notification
// note: topicID can not be mixed/matched with other IDs types in same notification
Notification options <topics> <deviceID> <registered_ids>¶
iOS, Android currently Supported options for notifications
iOS only:
* setBbadge (int)
* setSubtitle (string)
Android only:
* setTag (string)
* setColor (string (hex #rrggbb color format))
// In Android 6 and lower - this the background color of the icon image when you pull down on the status bar messages
// In Android 7 and greater - this is the color of the icon itself when you pull down on the status bar messages
* setIcon (string)
// custom icon file must be in app itself
// icon must be drawable resource, if not set, FCM displays launcher icon in app manifest
// for consistency across Android OS versions(5.0 - 10.0), use a material design, transparent icon
// if using icon in `drawable-XYdi` folders, use icon name without file extension, ie: ->setIcon('myIcon')
// if using icon from other location, you must specificy the file extension, ie: ->setIcon('www/images/thisIcon.png')
// for more info, see: https://github.com/arnesson/cordova-plugin-firebase/issues/764
*** future: android_channel_id
Both:
* setTitle (string)
* setBody (string)
* setSound (string)
// custom sound must be in the app itself
// custom sound file must be in /res/raw/
*** future: click_action
*** future: body_loc_key
*** future: body_loc_args
*** future: title_loc_key
*** future: title_loc_args
//NOTE: You can mix and match iOS and Android only options in same notification
//NOTE: if iOS/Android don't recognize an option used in the other platform, that option is simply discarded/ignored.
Notification DATA options <topics> <deviceID> <registered_ids>¶
Client app is responsible for processing data messages. Data messages require custom key-value pairs that your app will understand.
* addData("key","value") - add data key/values one at a time
* addDataArray(array_of_keyValues) - add data as a prebuilt object array
// $fcmData = array(
// 'action' => 2,
// 'dataTitle' => "This is my subject line",
// 'dataMsg' => "This is the body of my message
// Example, In a cordova based app using `cordova-plugin-firebase`
window.FirebasePlugin.onNotificationOpen(function(payload) {
// if there is a payload it will be in payload object
if (payload.action == 1) { // email verification confirmation
setDB("user_emailVerify",payload.user_emailVerify) ;
alert("Thank you, your email address has now been verified") ;
} else if (payload.action == 2) { // display gen message
alert(payload.dataTitle+ "\n" +payload.dataMsg) ;
}
}, function(error) {
console.error(error);
}) ;
// NOTE: you can mix/use ->addDataArray(array()) and ->addData("key","value") in same notification
// NOTE: pass in preset array, then add a few extra custom key/values.
Data Only message¶
Client app is responsible for processing data messages. Data messages have only custom key-value pairs.
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
$notification = new \Fcm\Push\Data();
$notification
->addData('test', '123');
->addRecipient($deviceId)
// Shortcut function:
// $notification = $client->pushData(['key' => 'value'], $deviceId);
$response = $client->send($notification);
Example response:
array(5) {
'multicast_id' =>
int(76762359248473280622)
'success' =>
int(1)
'failure' =>
int(0)
'canonical_ids' =>
int(0)
'results' =>
array(1) {
[0] =>
array(1) {
'message_id' =>
string(35) "0:1524927061384248%c5f39c08f9fd7ecd"
}
}
}
Managing Device Groups¶
With device group messaging, you can send a single message to multiple instances of an app running on devices belonging to a group. Typically, “group” refers a set of different devices that belong to a single user. All devices in a group share a common notification key, which is the token that FCM uses to fan out messages to all devices in the group. Read more on at official documentation.
Creating a device group¶
When creating a new group, the response will contain a notification key, which will be used when adding or removing devices from the group, and sending messages to it.
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
$newGroup = new \Fcm\DeviceGroup\Create('phones');
$newGroup->addDevice($deviceId);
// Shortcut function:
// $client->deviceGroupCreate('phones', $deviceId);
$client->send($newGroup);
Example response:
array(1) {
'notification_key' =>
string(119) "APA91bE8asD44A2gjSUJqRp8Ym4pe7TlrlrSLVkKRBdvkoWOFmusdc87934ASDURl8xaUbXXdKC5DRkUssYtkOl_lnWXT7gF0vO9E666XeL1qJs02FsunJ4"
}
Adding devices to a group¶
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
$group = new \Fcm\DeviceGroup\Update('phones', $notificationKey);
$group->addDevice($deviceId);
// Shortcut function:
// $client->deviceGroupUpdate('phones', $notification_key, $deviceId);
$client->send($group);
Example response:
array(1) {
'notification_key' =>
string(119) "APA91bE8asD44A2gjSUJqRp8Ym4pe7TlrlrSLVkKRBdvkoWOFmusdc87934ASDURl8xaUbXXdKC5DRkUssYtkOl_lnWXT7gF0vO9E666XeL1qJs02FsunJ4"
}
Removing devices from a group¶
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
$group = new \Fcm\DeviceGroup\Remove('phones', $notificationKey);
$group->addDevice($deviceId);
// Shortcut function:
// $client->deviceGroupRemove('phones', $notification_key, $deviceId);
$client->send($group);
Example response:
array(1) {
'notification_key' =>
string(119) "APA91bE8asD44A2gjSUJqRp8Ym4pe7TlrlrSLVkKRBdvkoWOFmusdc87934ASDURl8xaUbXXdKC5DRkUssYtkOl_lnWXT7gF0vO9E666XeL1qJs02FsunJ4"
}
Managing Notification Topics¶
Based on the publish/subscribe model, FCM topic messaging allows you to send a message to multiple devices that have opted in to a particular topic. You compose topic messages as needed, and FCM handles routing and delivering the message reliably to the right devices.
For example, users of a local weather forecasting app could opt in to a “severe weather alerts” topic and receive notifications of storms threatening specified areas. Users of a sports app could subscribe to automatic updates in live game scores for their favorite teams.
Read here for more information.
Subscribing to a topic¶
When a topic does not exist, you can still subscribe to it, and the topic will be automaticly created.
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
$subscribe = new \Fcm\Topic\Subscribe('my_topic_name');
$subscribe->addDevice($deviceId);
// Shortcut function:
// $client->topicSubscribe('my_topic_name', $deviceId);
$client->send($subscribe);
Example response:
// When an error occurs, this will be filled with the message.
array(1) {
'results' =>
array(1) {
[0] =>
array(0) {
}
}
}
Unsubscribing from a topic¶
Just like creating a topic, a topic will be automaticly deleted once all devices are unsubscribed from it.
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
$unsubscribe = new \Fcm\Topic\Unsubscribe('my_topic_name');
$unsubscribe->addDevice($deviceId);
// Shortcut function:
// $client->topicUnsubscribe('my_topic_name', $deviceId);
$client->send($unsubscribe);
Example response:
// When an error occurs, this will be filled with the message.
array(1) {
'results' =>
array(1) {
[0] =>
array(0) {
}
}
}
Package Options¶
Package options allow you to set options used within calls in the package. Package options can be configured in two ways.
Options¶
Options are set as an array. Options can be set on client instantiation or on an already created client.
<?php
$options = Array("http_errors" => true);
?>
Currently only one option is supported.
For any other sugestions for options, please add an issue to https://github.com/EdwinHoksberg/php-fcm/issues describing the new option.
Setting on instantiation¶
Settings options on instance creation is done as follows.
<?php
$options = Array("http_errors" => true);
$client = new \Fcm\FcmClient($serverKey, $senderId, $options);
Setting after instantiation¶
Options can be set after instantiation using the setOptions function passing in an options array.
<?php
$client = new \Fcm\FcmClient($serverKey, $senderId);
# some code using the client
$options = Array("http_errors" => true);
$client->setOptions($options);
# some more code using the client
$options = Array("http_errors" => false);
$client->setOptions($options);
http_errors option¶
The http_errors option exposes the Guzzle http_errors parameter. By default, a HTTP error in Guzzle will cause an exception, so will terminate your code. By setting http_errors to false a HTTP error will not result in an exception.
An example of setting the options array might look like this.
<?php
$options = Array("http_errors" => true);
Guzzle is the underlying library used by php-fcm, see http://docs.guzzlephp.org/en/stable/ for more details.
The http-errors option is described at http://docs.guzzlephp.org/en/stable/request-options.html#http-errors
Maintainer and Contributor Notes¶
These are notes for package maintainers and contributors.
The intention is to release a new version every 3 months, if code has changed in a useful way.
Creating a new release¶
New releases can be done via the github web interface at: https://github.com/EdwinHoksberg/php-fcm/releases/new
Current tags: https://github.com/EdwinHoksberg/php-fcm/tags
Releases: https://github.com/EdwinHoksberg/php-fcm/releases
Releases on packagist: https://packagist.org/packages/edwinhoksberg/php-fcm
Create a tag:
git tag v1.2.0
git push origin v1.2.0
Further reading…
Automated tests¶
Automated tests are in https://github.com/EdwinHoksberg/php-fcm/tree/master/tests
Automated test runs can be viewed at: https://travis-ci.org/github/EdwinHoksberg/php-fcm