Skip to content

Instantly share code, notes, and snippets.

@rolinger
Last active April 2, 2024 03:54
Show Gist options
  • Star 53 You must be signed in to star a gist
  • Fork 21 You must be signed in to fork a gist
  • Save rolinger/d6500d65128db95f004041c2b636753a to your computer and use it in GitHub Desktop.
Save rolinger/d6500d65128db95f004041c2b636753a to your computer and use it in GitHub Desktop.
PHP => FCM Push notification tutorial for Android and iOS
Below is a full tutorial on how to setup and use Googles Firebase push notification API for both Android and iOS. It is based on this
earlier implementation of Googles GCM method: https://gist.github.com/prime31/5675017 - FCM is the new method and GCM will eventually be
retired.
## THE BELOW METHOD IS THE NEWER FCM METHOD:
Register your app in the FCM Console: https://console.firebase.google.com (add project)
1. Click on the newly added project, in the upper left menu is the "Overview" and Gear Settings.
2. Click on the GEAR settings icon, and then on "Project Settings"
3. In the main screen, click on "Cloud Messaging"
4. Here you will find both your "Server Key" and "SenderID"
5. The "Server Key" is what is used below as the API_ACCESS_KEY
6. The "SenderID" is what your app (on the client phone) will need to generate a 'registration_ID'
7. You now need to register the "senderID" in your developer play console of your app
8. Go to: https://play.google.com, login to manage your app on the playstore
9. Click on the specific app and in the left menu under "Development Tools" click on "Serivces & APIs"
10. Under the Firebase Cloud Messaging (FCM) section, click "Link Sender ID", add your "server key" and click "link". After it links, your "senderID" will appear in the linked section.
OLD 11. In your App, (I use Cordova => phonegap-plugin-push plugin), make a call the FCM server, passing the senderID
NEW 11. I now use `cordova-plugin-firebasex` - a much more rebust and supported plugin that full integrates all of Firebase SDK into your project. In your App, make a call to the FCM server, passing the senderID
12. The client App will receive the "registration_ID". - this is a unique ID that specifically registers the users phone
to receive messages on behalf of your app.
13. Your app will need to pass the 'registration_ID' to your server. In my case, my app passes it via an api call. But
your app could simply pass a silent url call to your server to capture the users 'registration_ID'
(ie: http://yourserver.com/passID.php?userID=jdoe&regID=$registration_ID).
14. Ideally, you will want to store that registration_ID locally on your server (mysql).
15. In the future, when you need to push a notification to that user, call up the stored registration_ID and pass it to
the script below:
`NOTE: Once your register your app in the FCM console and retrieve your Server Key and SenderID, it might take 12 to 24 hours
for the IDs to propagate to the FCM messaging servers. I experienced this, minutes after registering my code worked but phone
never received the messages...10 hours later...no changes to my code...phone suddenly started getting the messages. I assume
it was a propagation issue.`
## REGISTERING YOUR APPLE APNs KEY in GOOGLE'S FCM CONSOLE:
1. You will need to link the Apple version of your app to your FCM App project. On the Firebase project main page, click add "+ Add another App". Then "iOS App"
2. After it is linked, in the same section as #4 & #5 above, you will see a section for "iOS Apps" and you should see
your App name listed
3. Here you can add your APNs Auth Key ....OR....add APNs Certificates - it is easier and recommend to do the Auth Key method.
4. Login to your Apple Developer Account: https://developer.apple.com/
5. Click on "Account" , then on "Certificates, IDs & Profiles"
6. Make certain your on the "ALL" section in the left hand menu, the click the (+) sign in the top right of the main screen
7. Under the "Production" section, select the "Apple Push Notification Authentication Key (Sandbox & Production) option.
8. Click on continue
9. You will be provided with an Auth Key AND a downloadable authkey file - you will need both. Download the file - but
do NOT change the name of the file
10. While here copy down your Team ID - click on "Account" again, then on "Membership" in the left hand menu
11. Copy your "Team ID"
12. Back in the FCM Console (#3), click on the "add/upload" button in the Apple APNs section next to your listed app.
13. KeyID = #9 Auth Key, File = "#9 downloaded file", App ID Prefix = "#11 Team ID"
14. Save/upload
`You iOS app is now registered with Googles FCM, Google FCM can now send/relay messages to iPhones/iPads
The only remaining step is to have your client iOS/iPhone App retrieve and send a proper registrationID to your server
side script (below). In my case, the same Cordova phonegap-plugin-push plugin extracts the Apple registrationID too.`
`NOTE: If you are integrating the Firebase SDK into a phonegap/cordova project, when your App launches it will try to connect to Firebase Crashlytics automatically, you will need to setup Crashlytics in our FCM App Project. If you are using Fabric in our current project you will need to link your Fabric account to your FCM Project App or you will get [Fabric] errors in the app launch. How to link Fabric to FCM Crashlytics: https://proandroiddev.com/migrating-crashlytics-to-the-firebase-console-5e05b6ff8c12`
// I migrated my server side code to a php-fcm class project, making server side FCM notification mgmt MUCH easier and cleaner.
// The guy who wrote the original no longer supports it so I expanded it out to include a lot more functionality and plan
// on adding more.
//
// NEW PHP SERVER SIDE CODE
// https://github.com/rolinger/php-fcm
<?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')
->addData('key', 'value'), // add single key/value pair
->addDataArray($myArray); // add preset array of key/value
// Send the notification to the Firebase servers for further handling.
$client->send($notification);
//
// OLD PHP SERVER SIDE CODE BELOW -
//
<?php
// API access key from Google FCM App Console
define( 'API_ACCESS_KEY', 'AAAAkPyMydI:A.............FWPt6AfWsrEFb6Ww' );
// generated via the cordova phonegap-plugin-push using "senderID" (found in FCM App Console)
// this was generated from my phone and outputted via a console.log() in the function that calls the plugin
// my phone, using my FCM senderID, to generate the following registrationId
$singleID = 'eEvFbrtfRMA:APA91bFoT2XFPeM5bLQdsa8-HpVbOIllzgITD8gL9wohZBg9U.............mNYTUewd8pjBtoywd' ;
$registrationIDs = array(
'eEvFbrtfRMA:APA91bFoT2XFPeM5bLQdsa8-HpVbOIllzgITD8gL9wohZBg9U.............mNYTUewd8pjBtoywd',
'eEvFbrtfRMA:APA91bFoT2XFPeM5bLQdsa8-HpVbOIllzgITD8gL9wohZBg9U.............mNYTUewd8pjBtoywd'
'eEvFbrtfRMA:APA91bFoT2XFPeM5bLQdsa8-HpVbOIllzgITD8gL9wohZBg9U.............mNYTUewd8pjBtoywd'
) ;
// prep the bundle
// to see all the options for FCM to/notification payload:
// https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support
// 'vibrate' available in GCM, but not in FCM
$fcmMsg = array(
'body' => 'here is a message. message',
'title' => 'This is title #1',
'sound' => "default",
'color' => "#203E78"
);
// I haven't figured 'color' out yet.
// On one phone 'color' was the background color behind the actual app icon. (ie Samsung Galaxy S5)
// On another phone, it was the color of the app icon. (ie: LG K20 Plush)
// 'to' => $singleID ; // expecting a single ID
// 'registration_ids' => $registrationIDs ; // expects an array of ids
// 'priority' => 'high' ; // options are normal and high, if not set, defaults to high.
$fcmFields = array(
'to' => $singleID,
'priority' => 'high',
'notification' => $fcmMsg
);
$headers = array(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fcmFields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result . "\n\n";
?>
@nachodd
Copy link

nachodd commented Jun 12, 2017

Thanks man! awesome guide!

@nachodd
Copy link

nachodd commented Jun 12, 2017

Just to know:
To make it work on a DEVELOPMENT ENVIROMENT (i.e. APP it's not in Play Store), i've got the TOKEN from the android APP using
String token = FirebaseInstanceId.getInstance().getToken();
and use this token as the 'registration_ID' (or singleID) to send to the notification to the phone.

@lionalex
Copy link

Why I receive push but without banner to top?
With another cellulare I don't receive notification when the app is closed....why?

@kailast
Copy link

kailast commented Sep 13, 2017

I have done all set up as per ## REGISTERING YOUR APPLE APNs KEY in GOOGLE'S FCM CONSOLE, I got the notification in android but not in IOS device. please give me the suggestion for IOS notification.

please give me the suggestion for IOS notification.

@masterBrass
Copy link

masterBrass commented Sep 15, 2017

@nachodd
Can you explain how you obtain the token on a development environment? Have you installed some plugins that use FCM?

At point #11. "In your App, (I use Cordova => phonegap-plugin-push plugin), make a call the FCM server, passing the senderID", can i help me?

@Defcon0
Copy link

Defcon0 commented Nov 2, 2017

AWESOME!! Works like a charm 👍

@i-asimkhan
Copy link

This code works like a charm.

$url = "https://fcm.googleapis.com/fcm/send";
$token = "";
$serverKey = '';
$title = "Title";
$body = "Body of the message";
$notification = array('title' =>$title , 'text' => $body, 'sound' => 'default', 'badge' => '1');
$arrayToSend = array('to' => $token, 'notification' => $notification,'priority'=>'high');
$json = json_encode($arrayToSend);
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: key='. $serverKey;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_CUSTOMREQUEST,

"POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
//Send the request
$response = curl_exec($ch);
//Close request
if ($response === FALSE) {
die('FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);

?>

@andymurakami
Copy link

The on('notification') event is not fired... anybody have a same problem ?

@HardikPatelIVision
Copy link

@andymurakami

Please explain what you are trying to say

@ratoncse24
Copy link

badge is not arrived and update on app icon !!

@harsh-sri
Copy link

Awesome Explanation buddy :)

@iggtony
Copy link

iggtony commented Mar 13, 2018

The format of the message is wrong for android.

here is my full code and works:

          $body = array(
		"to" => $token,
		"notification" => array(
			"title" => "Simple FCM Client",
            "body" => "Click me to go to detail",
            "sound" => "default"
		),
		"data" => array("targetScreen" => "detail"),
		"priority" => 10
	);
	if ($platform == 'android') {
		$body = array(
			"to" => $token,
			"data" => array(
				"custom_notification" => array(
                        "title" => "Simple FCM Client",
                        "body" => "Click me to go to detail",
                        "sound" => "default",
                        "priority" => "high",
                        "show_in_foreground" => true,
                        "targetScreen" => 'detail'
                 )
			),
			"priority" => 10
		);
	}

	$headers = array(
		'Content-Type: application/json',
		'Authorization: key=' . $serverKey
	);

	if($ch = curl_init()) {
		curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
		$result = curl_exec($ch );
		curl_close( $ch );
		echo $result . "\n\n";
	}

@EliakimRamos
Copy link

Hey, how are you, I have a problem the code return is successful, but the notification does not arrive in my application, how to fix this?

@guilhermelirio
Copy link

Thanks! You have example to change iOS sound notification?

@SweetyKothari
Copy link

Hi,
I am facing some issue in android based application : Push notification .
FCM is configured ,when I am pushing message from FCM console nothing is arriving on phone. Also on console it shows 'Completed', however sent is still 0 %

@nivekalara237
Copy link

work!! for me thank u

@fidalgodev
Copy link

fidalgodev commented Sep 26, 2018

This is my code on my app.js, on devide ready:

const push = PushNotification.init({
        android: {
        },
        browser: {
            pushServiceURL: 'http://push.api.phonegap.com/v1/push'
        },
        ios: {
            alert: "true",
            badge: "true",
            sound: "true"
        },
        windows: {}
    });
    
    push.on('registration', (data) => {
        //alert(data.registrationId);
        var registrationId=data.registrationId;
            var dataString ="id_usuario="+registrationId;
            if($.trim(registrationId).length>0){
                $.ajax({
                    type: "POST",
                    url: "https://pizzarte.com/app/registarid.php",
                    data: dataString,
                    crossDomain: true,
                    cache: false,
                })
            }
    });

    push.on('notification', (data) => {
        // data.message,
        // data.title,
        // data.count,
        // data.sound,
        // data.image,
        // data.additionalData
    });
    
    push.on('error', (e) => {
        // e.message
    });

Im getting the alert with my token. It gets stored on my database. On my php i have:

<?php
 

$url = "https://fcm.googleapis.com/fcm/send";
$token = "device_id_token_got_from_the_db";
$serverKey = 'server_key_coppied_from_cloud_messaging_on_google_console_project';
$title = "Title";
$body = "Body of the message";
$notification = array('title' =>$title , 'text' => $body, 'sound' => 'default', 'badge' => '1');
$arrayToSend = array('to' => $token, 'notification' => $notification,'priority'=>'high');
$json = json_encode($arrayToSend);
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: key='. $serverKey;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_CUSTOMREQUEST,

"POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
//Send the request
$response = curl_exec($ch);
//Close request
if ($response === FALSE) {
die('FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);

?>

When i execute the php i get this:

{"multicast_id":7523410050003479652,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}

I already tried to compile the .apk, run it on my mobile, the token gets insert on the database as well, but i always get that error when trying to send the notification from the .php file...

@afunworm
Copy link

This is my code on my app.js, on devide ready:

const push = PushNotification.init({
        android: {
        },
        browser: {
            pushServiceURL: 'http://push.api.phonegap.com/v1/push'
        },
        ios: {
            alert: "true",
            badge: "true",
            sound: "true"
        },
        windows: {}
    });
    
    push.on('registration', (data) => {
        //alert(data.registrationId);
        var registrationId=data.registrationId;
            var dataString ="id_usuario="+registrationId;
            if($.trim(registrationId).length>0){
                $.ajax({
                    type: "POST",
                    url: "https://pizzarte.com/app/registarid.php",
                    data: dataString,
                    crossDomain: true,
                    cache: false,
                })
            }
    });

    push.on('notification', (data) => {
        // data.message,
        // data.title,
        // data.count,
        // data.sound,
        // data.image,
        // data.additionalData
    });
    
    push.on('error', (e) => {
        // e.message
    });

Im getting the alert with my token. It gets stored on my database. On my php i have:

<?php
 

$url = "https://fcm.googleapis.com/fcm/send";
$token = "device_id_token_got_from_the_db";
$serverKey = 'server_key_coppied_from_cloud_messaging_on_google_console_project';
$title = "Title";
$body = "Body of the message";
$notification = array('title' =>$title , 'text' => $body, 'sound' => 'default', 'badge' => '1');
$arrayToSend = array('to' => $token, 'notification' => $notification,'priority'=>'high');
$json = json_encode($arrayToSend);
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: key='. $serverKey;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_CUSTOMREQUEST,

"POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
//Send the request
$response = curl_exec($ch);
//Close request
if ($response === FALSE) {
die('FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);

?>

When i execute the php i get this:

{"multicast_id":7523410050003479652,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}

I already tried to compile the .apk, run it on my mobile, the token gets insert on the database as well, but i always get that error when trying to send the notification from the .php file...

Have you found out how to fix it yet? I have the exact same problem and to my understanding, it is because the app register the registrationID with phonegap as a sender, so if you send using a different PHP platform, it wouldn't work. Sadly, I do not know how to fix it yet. Please let me know if you find anything.

@norrisboat
Copy link

Not all heroes wear capes. Thanks!!

@silmymaster
Copy link

working php code..!

define( 'API_ACCESS_KEY', 'AAAAGu0VD0c:APA91bEJqQk5KAzS4j-3DemjWlM6gYtt3Vjb4MH_9P54uj5e9NQomiwaZKKhQoTTNMFmPr767uFHJd27umYjc4nBZb-EHohGDdM84Pb6-vHQpiSen2MvCXyJ-XyZ0shyw30MpVPufwel' );

// generated via the cordova phonegap-plugin-push using "senderID" (found in FCM App Console)
// this was generated from my phone and outputted via a console.log() in the function that calls the plugin
// my phone, using my FCM senderID, to generate the following registrationId

$singleID = 'd1iCe7YxARo:APA91bFKOafJsgCvqwoj33Ri_CJs_cixrdUI4tBKzPuomvBlDSNrKOU_nd41vhAqVuu20q8rZtqi2Vm_SRALJVSXDbeWfeCvqi8TyFvacGleNcD2ZR9Gp-_9OoZNchZ1P72X4y9xsXMD';

// prep the bundle
// to see all the options for FCM to/notification payload:
// https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support

// 'vibrate' available in GCM, but not in FCM
$fcmMsg = array(
'body' => 'here is a message. message',
'title' => 'This is title #1',
'sound' => "default",
"show_in_foreground" => true,
"targetScreen" => 'detail',
'color' => "#203E78"
);
// I haven't figured 'color' out yet.
// On one phone 'color' was the background color behind the actual app icon. (ie Samsung Galaxy S5)
// On another phone, it was the color of the app icon. (ie: LG K20 Plush)

// 'to' => $singleID ; // expecting a single ID
// 'registration_ids' => $registrationIDs ; // expects an array of ids
// 'priority' => 'high' ; // options are normal and high, if not set, defaults to high.
$fcmFields = array(
'to' => $singleID,
'priority' => 'high',
'notification' => $fcmMsg
);

$headers = array(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);

$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fcmFields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result . "\n\n";

@rolinger
Copy link
Author

@iggtony and Everyone. FCM has changed a lot since I originally did this write up. It now has Android & iOS specific message handling on both the sending and receiving side of the message. The above PHP code to send notifications is for Googles Legacy HTTP, there is the newer FCM HTTP API method now that differentiates sending/receiving Android vs iOS messages. As well, at the time of my original write up I was using the phonegap-pushnotification plugin, and I have now switched to the cordova-plugin-firebasex plugin - which I believe supports both cordova and phonegap - I would recommend moving to it as it is the full Firebase SDK with actual maintained support - with WELL documented notification receive handling. I also reference newer server side PHP code in the original write up - it still uses Legacy HTTP but I plan on adding in support for the newer API methods. At a minimum, the php-fcm I link to above will make your server side lives a lot easier.

@sgnm-sevgicorumlu
Copy link

sgnm-sevgicorumlu commented Oct 19, 2020

define('API_ACCESS_KEY', 'AA:XX .... '); /* Firebase Server key */


$singleID = ''; /* FIREBASE TOKEN */

$fcmMsg = array(
    'body' => 'here is a message. message',
    'title' => 'This is title #1',
    'sound' => "default",
    'color' => "#203E78"
);


$fcmFields = array(
    'to' => $singleID, /* FIREBASE TOKEN */
    'priority' => 'high',
    'notification' => $fcmMsg
);

$headers = array(
    'Authorization: key= ' . API_ACCESS_KEY,
    'Content-Type: application/json'
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fcmFields));
$result = curl_exec($ch);
curl_close($ch);
echo $result . "\n\n";

the error i received is attached
{"multicast_id":xxx,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
can you help me

@sgnm-sevgicorumlu
Copy link

sgnm-sevgicorumlu commented Oct 19, 2020

I can't send mobile notification. {"error":"InvalidRegistration"}

@cgkronos
Copy link

cgkronos commented Mar 25, 2022

I'm curious, I try to find an updated version of this tutorial for the V1 of API Firebase Cloud Messaging with no success (I'm seeking an example step by step and not just the changes between the legacy version and V1)

Thanks in advance for your help

@rolinger
Copy link
Author

@everyone -

For anyone using PHP server side, I am co-author of : https://github.com/EdwinHoksberg/php-fcm

It wasn't supported for a while so I forked it and modified it, then the orig developer gave me and a few others full access to admin his repo. After we gained access several of us merged our forks back to the master and now it is a supported and maintained repo with lots of functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment