Google Cloud Messaging using PHP

Google Cloud Messaging

Using PHP to send a message to a Google Cloud Messaging registered device is quite simple. In this example we'll be using curl to create a message request to send to the Google GCM server.

The code shown in this example is just going to demonstrate how to send a message to a registered device ID.

I'll leave the particulars of communicating the device registration id's up to you, however the process is fairly simple:

  • Register with the GCM service on your device, retrieving a registration ID and store in the application (This can be done through our native extension).
  • Send the registration ID to your server and store it on your server as a list of connected devices
  • When you wish to send a notification, use the appropriate registration ID in the data of your message

Firstly you'll need to sign up to the Google Cloud Messaging service. This process is outlined in the "Getting Started" section on the Android developer site: http://developer.android.com/guide/google/gcm/gs.html.

You need to follow these instructions to get your API keys. If you're using our native extension in AIR then anything further can be ignored (i.e. anything from "Install the Helper Libraries"), though you will need it when developing your own native application.

Once you've got your api key and your device id you're ready to send a message. The PHP function below implements a simple "send notification" function using a JSON formatted message package.

  1. /**
  2.  * The following function will send a GCM notification using curl.
  3.  *
  4.  * @param $apiKey [string] The Browser API key string for your GCM account
  5.  * @param $registrationIdsArray [array] An array of registration ids to send this notification to
  6.  * @param $messageData [array] An named array of data to send as the notification payload
  7.  */
  8. function sendNotification( $apiKey, $registrationIdsArray, $messageData )
  9. {
  10. $headers = array("Content-Type:" . "application/json", "Authorization:" . "key=" . $apiKey);
  11. $data = array(
  12. 'data' => $messageData,
  13. 'registration_ids' => $registrationIdsArray
  14. );
  15.  
  16. $ch = curl_init();
  17.  
  18. curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
  19. curl_setopt( $ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send" );
  20. curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
  21. curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
  22. curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
  23. curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($data) );
  24.  
  25. $response = curl_exec($ch);
  26. curl_close($ch);
  27.  
  28. return $response;
  29. }

To use this function you'll need to assemble the message data and an array of registration ids, as demonstrated below. The message data we construct here is an example of usage with our extension to automate the display of a notification when the GCM arrives on the device.

  1. // Message to send
  2. $message = "the test message";
  3. $tickerText = "ticker text message";
  4. $contentTitle = "content title";
  5. $contentText = "content body";
  6.  
  7. $registrationId = 'DEVICE_ID';
  8. $apiKey = "YOUR_BROWSER_API_KEY";
  9.  
  10. $response = sendNotification(
  11. $apiKey,
  12. array($registrationId),
  13. array('message' => $message, 'tickerText' => $tickerText, 'contentTitle' => $contentTitle, "contentText" => $contentText) );
  14.  
  15. echo $response;
  16.  

The echoed response will show the JSON GCM message package sent to the server, and as long as you have the correct device ID and a registered device, your notification will appear on your device. Happy messaging!

Published by

Michael

http://michaelarchbold.com

21 thoughts on “Google Cloud Messaging using PHP”

  1. I am getting the following error,
    {“multicast_id”:5895328265453837782,”success”:0,”failure”:1,”canonical_ids”:0,”results”:[{“error”:”MismatchSenderId”}]}

    1) I have written a simple PN gcm code on my mobile and got a registration ID from google.
    2) I have a paid developer account with google. I have got a API key – browser app.
    3) I have written a php file running on linux server. This file contains the registration ID, API Key, message I want to push. I am using curl functionality. But I am getting the error pasted above.
    Here goes my php code.

    $messageData,
    ‘registration_ids’ => $registrationIdsArray
    );

    $ch = curl_init();

    curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
    curl_setopt( $ch, CURLOPT_URL, “https://android.googleapis.com/gcm/send” );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($data) );

    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
    }

    $message = “the test message”;
    $tickerText = “ticker text message”;
    $contentTitle = “content title”;
    $contentText = “content body”;

    $registrationId = ‘APA91bE5l3UFCCFWUJDOWcCFfSRSXMf02dY5fRmFIzgGVsBnxVt82mKoxWTgoTryOAHxSQJP1OMRl5a6sMAuo7Xia_TqVeKKZkwBKOwdQmjv79JTHB-QCSKb-ciMFa5AIlGBrH_e30HOVeIdCAD8DjEZnZ4m8hlgRA’;
    $apiKey = “AIzaSyC1K5So6ZmjtDmgDH2dGREGAr7FKjYizOU”;

    $response = sendNotification(
    $apiKey,
    array($registrationId),
    array(‘message’ => $message, ‘tickerText’ => $tickerText, ‘contentTitle’ => $contentTitle, “contentText” => $contentText) );

    echo $response;
    ?>
    Can you please check.

  2. I unistalled the App and got a new reg ID. With this ID it works fine!.
    I am getting this message when I run my php file. {“multicast_id”:7102863698841510245,”success”:1,”failure”:0,”canonical_ids”:0,”results”:[{“message_id”:”0:1345624826914398%921c249af9fd7ecd”}]}

    I am getting a push notification on my simulator when I run the php script. But the message is null.
    Can you please send the android script to extract the message…

    1. Hi,

      You’re first problem was probably something to do with an old registration id on the device. Sometimes this happens if the ID had been issued under the old C2DM service. Otherwise you should just check your application setup on the Google service. Double check your ID’s, including the project ID, https://code.google.com/apis/console/#project:xxxxxxxxxxx which you should use as your sender ID on the client side.

      Processing of the received message is quite simple using the extra’s packaged with the received Intent. Google provide many samples for the Java code here: http://developer.android.com/guide/google/gcm/demo.html

      A quick example, this is how we process the JSON data sent with the received Intent:

      private void processMessage(Context context, Intent intent) 
      {
      	Log.i( "EXAMPLE", "processMessage()");
      	try 
      	{
      		Set ks = intent.getExtras().keySet();
      		JSONObject json = new JSONObject();
      		for (String is: ks)
      		{
      			json.put( is, intent.getStringExtra(is) );
      		}
      		String parameters = json.toString();
      
      		//
      		// Do whatever you need to here....
      		//
      	}
      	catch (Exception e) 
      	{
      		Log.e( "EXAMPLE", e);
      	}
      } 
      

      This function should be called from within your onMessage handler.

      public class GCMIntentService extends GCMBaseIntentService
      {
          ... Rest of the class is not shown ...
      
          @Override
          protected void onMessage(Context context, Intent intent) 
          {
              Log.i( "EXAMPLE", "Received message");
              processMessage(context, intent);
          }
          
          ...
      }
      
  3. Hi,

    I’m very pleased so far with your notification Native Extension, even though a complete tutorial would be really nice (for android and ios). I’ve tested the whole system on Android for now and the only problem I’ve got is getting back the JSON content when the app is in the background or not running. This event doesn’t seem to be triggered:
    PushNotifications.service.addEventListener( PushNotificationEvent.NOTIFICATION, pn_notificationHandler );

    Should it be in the main class of the app? I kinda struggle with the whole concept of “your app still receive event notification, even though it’s not on”.

    Thanks

    1. Currently applications will only receive the events if the application is running in the background. We’re looking into ways around this limitation.

      When a notification is received by the device you should provide the additional information specified in the documentation (tickerText, contentTitle etc) to display a notification in the device’s notification area. When this notification is selected by the user, your application will start up. If it was running in the background it will receive the notifications payload, otherwise (as advised in the documentation) you should check your server for outstanding/latest messages.

      Hope this helps.

      Michael

  4. It does help! Thank you. 🙂

    Is it the same with iOS? I guess so

    (it would be a good idea for the website to get a forum so we users could help each other while the tutorial are being made)

  5. Antoine,

    Yes it’s very similar on iOS, though the implementation is slightly different the end result is currently the same.

    We are currently looking at options for a forum and wiki space and should have something up soon.

    Cheers

  6. The extension works great with the app in the foreground but sometimes the event is not fired when the app is in the background. Any idea what could cause this?
    I’m thinking of using the same trick than when the app is opened (aka check on the server for any new missed push) but it’s not the best solution.

  7. Antoine,

    Sometimes the GCM messages take a while to arrive when the application has been put into background operation. It isn’t a guaranteed delivery service either. This sort of check should be done on your server, you can check the delivery state with the GCM servers and see if the message failed or has been delivered.

    Cheers

  8. Michael,

    The GCM push notifications works pretty well using the distriqt libraries.

    I have a question regarding the handling of the intent message: Is there a way through which it is possible to display only certain push notifications, for others, either ignore/do something else (like sync silently)

    Thanks

    1. @Parth

      On Android if you don’t pass the tickerText, contentTitle and message the data will still be passed through to your application without displaying a notification. However if the application is running in the background, there is no way for your application to be activated and receive the data, so this method only works when your application is running in the foreground.

  9. Hello Guys,

    I am using phonegap build to build my android and ios apps, and i want to send them push notification programatically from my server. The thing I dont know here is how to get Registraion id on android, as I have registered for GCM notifications succefully, but dont know how to get registration id. ( i doubt its not the same PROJECT NUMBER being used as sender id).

    Waiting eagerly…great souls..merci on me please.. 😉

    1. Hi,

      The registration id is retrieved from the device and is definitely not your sender id. I’m not aware of how to do this through PhoneGap though it’s quite easy using our extensions in AS3, however you will need client side code sending the id to your server. It’ll depend on how you’re implementing it in your PhoneGap application.

      The basic process is
      – a device registers with GCM using your sender id
      – the device is assigned an registration id, which your application needs to retrieve and send to your server
      – your server stores the registration id’s and then uses them to send messages when appropriate

      Regards,
      Michael

  10. Hi Michael,

    I have been using this code to send notification since one year now.After ignoring one issue since begining, I am now at point where i can no more ignore it.
    The issue is “How to use payload”.

    my $messageData is this array(‘message’ => $message, ‘matchId’ => $matchId, ‘contentTitle’ => $contentTitle, “contentText” => $contentText)

    but on the device side i can just use first key (message) and others just show undefined.

    Note: I am using phonegap to make applications and phonegap has a plugin to read pushnotifications.

    1. Please ignore my previous question( i didnt find a way to delete it).

      For those who know phonegap and have same question, the answer is :

      The message text can be retrieved with: e.message

      All other key/value pairs can be retrieved with: e.payload.key

      Thanks!

  11. Hi Guys

    Thanks for the extension. I have a small issue. Token registers fine, and I am getting all 3 the notification events fire when the app is running.

    PushNotificationEvent.NOTIFICATION
    PushNotificationEvent.BACKGROUND_NOTIFICATION
    PushNotificationEvent.FOREGROUND_NOTIFICATION

    But at no point do any messages appear in my notification centre. on Android. Also one thing to note. PushNotifications.service.getStatus() after register is NULL.

    Any ideas

    1. Hey,

      If you don’t mind, use our support site for questions. We don’t often check the blog for questions on our extensions.

      Cheers

  12. Hi blogger, i found this post on 14 spot in google’s search results.

    You should decrease your bounce rate in order to rank in google.
    This is major ranking factor nowadays. There is very useful wordpress plugin which can help you.
    Just search in google for:
    Lilas’s Bounce Plugin

Leave a Reply

Your email address will not be published. Required fields are marked *