Sending Android Push Notifications from PHP to phonegap applications


Last days I’ve been working within a Phonegap project for Android devices using Push Notifications. The idea is simple. We need to use the Push Notification Plugin for Android. First we need to register the Google Cloud Messaging for Android service at Google’s console, and then we can send Push notifications to our Android device.

The Push Notification plugin provides a simple example to send notifications using Ruby. Normally my backend is built with PHP (and sometimes Python) so instead of using the ruby script we are going to build a simple PHP script to send Push Notifications.

The script is very simple

<?php
$apiKey = "myApiKey";
$regId = "device reg ID";

$pusher = new AndroidPusher\Pusher($apiKey);
$pusher->notify($regId, "Hola");

print_r($pusher->getOutputAsArray());

And the whole library you can see here:

<?php
namespace AndroidPusher;

class Pusher
{
    const GOOGLE_GCM_URL = 'https://android.googleapis.com/gcm/send';

    private $apiKey;
    private $proxy;
    private $output;

    public function __construct($apiKey, $proxy = null)
    {
        $this->apiKey = $apiKey;
        $this->proxy  = $proxy;
    }

    /**
     * @param string|array $regIds
     * @param string $data
     * @throws \Exception
     */
    public function notify($regIds, $data)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, self::GOOGLE_GCM_URL);
        if (!is_null($this->proxy)) {
            curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
        }
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->getPostFields($regIds, $data));

        $result = curl_exec($ch);
        if ($result === false) {
            throw new \Exception(curl_error($ch));
        }

        curl_close($ch);

        $this->output = $result;
    }

    /**
     * @return array
     */
    public function getOutputAsArray()
    {
        return json_decode($this->output, true);
    }

    /**
     * @return object
     */
    public function getOutputAsObject()
    {
        return json_decode($this->output);
    }

    private function getHeaders()
    {
        return [
            'Authorization: key=' . $this->apiKey,
            'Content-Type: application/json'
        ];
    }

    private function getPostFields($regIds, $data)
    {
        $fields = [
            'registration_ids' => is_string($regIds) ? [$regIds] : $regIds,
            'data'             => is_string($data) ? ['message' => $data] : $data,
        ];

        return json_encode($fields, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);
    }
}

Maybe we could improve the library with a parser of google’s ouptuput, basically because we need to handle this output to notice if the user has uninstalled the app (and we need the remove his reg-id from our database), but at least now it cover all my needs. You can see the code at github

63 thoughts on “Sending Android Push Notifications from PHP to phonegap applications

  1. That is a very useful class, I have wanted to do push notifications to one of my apps. Thank you for sharing!

    1. Do you think you could have a tutorial on getting phone’s registration Ids and storing them to mysql databases?

      If you could I would be incredibly grateful. Thank you!

  2. hello, I have a problem.
    The code gives me this error:
    PHP Parse error: syntax error, unexpected ‘[‘ in /var/www/app/servicioApp/push.php on line 68

  3. Is it possible to include an URL to a page in the app in the push notification and if so, how would one go about achieving this?

  4. I got the registration Id from the Android device while running the app and placed in the file and ran the file. This is the error I got. Please help.

    [results] => Array ( [0] => Array ( [error] => InvalidRegistration )

    Thanks,
    Jack.

  5. My Scenario is that i want to send notification,working on a PHP website + hybrid app using j query Mobile and phone gap application and searching free API for android application, i have lot of users ids n i want when ever i update request for single user from my website send notification just on that particular device to that user.

    So my question is how to send push notification to registered users android, I want to send push message as soon as some one send request and from server reply back to that particular user. Please give me any idea what will be process to accomplish this task.

    Example:
    on website i have combobox in which two fields pending and complete on complete select i want to send notification on that particular device where user sent request to my website.
    not want to send multiple users in my scenerio just i will send notifcation to one device to that particular user who sending requent .

    can someone tell me how can i accomplish this task .
    second is any free API for that .
    Is there any starting point or give me code that i can proceed for it.

    regarding your code what things i have to do

    1. I don’t really understand. You don’t need any external API to do that. You only need the google API to send push notifications. First you need to register the push notifications in your app then your mobile app must send to the server the deviceID of your users. Then in the server with those deviceID you can send push notifications to all of them with a simple http request. The push plugin comes with a working example to that. The server side example is a ruby script, and this post does the same than this ruby script, but using PHP. I recommend to install the push plugin (it’s compatible with cordova3) and follow its instructions. It works like a charm

      1. i have done first thing as u told me sent device id to server .
        Second thing i used your script as u given for php as well as set google api key “XXXXXXXXXXXXXXXXXXXXXXXX”.
        but in script u used $app-> run why u used because its not instantiate in your code .
        third i got response after on this line .
        print_r($pusher->getOutputAsArray());

        Array
        (
        [multicast_id] => 4.8474865209653E+18
        [success] => 0
        [failure] => 1
        [canonical_ids] => 0
        [results] => Array
        (
        [0] => Array
        (
        [error] => InvalidRegistration
        )

        )

        )

        so whats the problem where i am wrong.

      2. ups! $app->run(); is a bug. I use this code in a silex app and I accidentally put it the Code Snippets. Anyway your output message isn’t because of this bug. It’s because your credentials aren’t ok. Remember that you need, not only the api key. You also need the device’s Id. You obtain the device Id when you register your device running your phonegap/cordova application.

        You can see how to obtain your device ID in plugin documentation https://github.com/phonegap-build/PushPlugin. There you can see the needed js code to register your device. It’s different with IOS and Android.

        You also need to take care with the phonegap/cordova version you are using. This post was written with cordova v2. Now cordova uses the v3. It’s similar, but the plugin architecture is a bit different (it’s much better in v3)

  6. Dear Gonzalo Ayuso i followed whole document and done but still one thing that i am not recieving reg id from back to GCm. what’s wrong .

    on andoid catlog i am recieving this msgs. but no where seeing reg id that’s will back from gcm.

    11-08 14:51:15.616: V/PushPlugin(1151): execute: action=register
    11-08 14:51:15.646: V/PushPlugin(1151): execute: data=[{“senderID”:”1014356851653″,”ecb”:”onNotificationGCM”}]
    11-08 14:51:15.666: V/PushPlugin(1151): execute: jo={“senderID”:”1014356851653″,”ecb”:”onNotificationGCM”}
    11-08 14:51:15.666: V/PushPlugin(1151): execute: ECB=onNotificationGCM senderID=1014356851653
    11-08 14:51:15.676: D/GCMRegistrar(1151): resetting backoff for org.apache.cordova.example
    11-08 14:51:15.776: V/GCMRegistrar(1151): Registering app org.apache.cordova.example of senders 1014356851653

    1. Ensure your project is properly configured in google’s console (https://cloud.google.com/console). Ensure Google Cloud Messaging for Android is enabled for your project properly configured (your browser keys). Ensure that you are using the properly senderID. And ensure your device can access to internet (3G enabled). Remember that provably it doesn’t work with emulators and you need real devices

      1. Gonzalo Ayuso i have check all things proper .
        and followed this documentation https://github.com/marknutter/GCM-Cordova
        after all setting and put my own sender id but in emulator its not showing me back reg is which backs from google.
        why i am not getting reg id.

        Output after follow this documention on emulatore.
        Cordova google cloud messaging pugin demo
        device ready event recieved
        Calling GCMRegistar.registar
        register our sender id with google

        i will be really thankful to you please if u have just 15 mintes can u check my all setting on teamviwer what ever time will you just i will online please it’s urgent i am trying more than 25 days but still not succed waiting for your good reply.

      2. window.plugins.GCM.register(“XXXXXXXXX”, “GCM_Event”, GCM_Success, GCM_Fail );

        Gcm Event Not trigering using implementation Cordova GCM

        its showing out put Just

        OutPut:-

        Cordova google cloud messaging pugin demo
        device ready event recieved
        Calling GCMRegistar.registar
        register our sender id with google

    1. GCM deprecated? maybe you are speaking about Android Cloud to Device Messaging (C2DM), but not GCM (it replaces C2DM)

  7. ya recently i saw its depreciated so is there any link push notification updated plugin files or link for using C2DM and other question is that is this php will still work with C2DM.
    Please kindly possible reply as soon as possible i am tired of from this notification.

  8. Here is catlog Output on android but u can see not getting register ID even not trigering GCM Event in used window.plugins.GCM.register(“my_app_id”, “GCM_Event”, GCM_Success, GCM_Fail );

    Please any one tell me what’s the prolem where i am wrong.

    11-09 20:17:06.180: I/CordovaLog(1245): Changing log level to DEBUG(3)
    11-09 20:17:06.190: I/CordovaLog(1245): Found preference for useBrowserHistory=true
    11-09 20:17:06.190: D/CordovaLog(1245): Found preference for useBrowserHistory=true
    11-09 20:17:06.190: I/CordovaLog(1245): Found preference for exit-on-suspend=false
    11-09 20:17:06.190: D/CordovaLog(1245): Found preference for exit-on-suspend=false
    11-09 20:17:06.220: D/DroidGap(1245): DroidGap.onCreate()
    11-09 20:17:06.550: D/CordovaWebView(1245): CordovaWebView is running on device made by: unknown
    11-09 20:17:06.570: D/JsMessageQueue(1245): Set native->JS mode to 2
    11-09 20:17:06.603: D/DroidGap(1245): DroidGap.init()
    11-09 20:17:06.640: D/CordovaWebView(1245): >>> loadUrl(file:///android_asset/www/index.html)
    11-09 20:17:06.654: D/PluginManager(1245): init()
    11-09 20:17:06.700: D/CordovaWebView(1245): >>> loadUrlNow()
    11-09 20:17:06.700: D/DroidGap(1245): Resuming the App
    11-09 20:17:06.780: D/SoftKeyboardDetect(1245): Ignore this event
    11-09 20:17:06.900: I/Choreographer(1245): Skipped 125 frames! The application may be doing too much work on its main thread.
    11-09 20:17:06.990: D/gralloc_goldfish(1245): Emulator without GPU emulation detected.
    11-09 20:17:07.271: I/Choreographer(1245): Skipped 190 frames! The application may be doing too much work on its main thread.
    11-09 20:17:07.271: D/SoftKeyboardDetect(1245): Ignore this event
    11-09 20:17:07.400: D/DroidGap(1245): onMessage(onPageStarted,file:///android_asset/www/index.html)
    11-09 20:17:10.820: D/chromium(1245): Unknown chromium error: -6
    11-09 20:17:11.450: D/dalvikvm(1245): GC_FOR_ALLOC freed 301K, 13% free 2718K/3100K, paused 38ms, total 41ms
    11-09 20:17:11.460: D/CordovaNetworkManager(1245): Connection Type: 3g
    11-09 20:17:11.460: D/DroidGap(1245): onMessage(networkconnection,3g)
    11-09 20:17:11.470: D/CordovaNetworkManager(1245): Connection Type: 3g
    11-09 20:17:11.492: D/DroidGap(1245): onMessage(spinner,stop)
    11-09 20:17:11.570: D/Cordova(1245): onPageFinished(file:///android_asset/www/index.html)
    11-09 20:17:11.570: D/DroidGap(1245): onMessage(onPageFinished,file:///android_asset/www/index.html)
    11-09 20:17:11.660: V/GCMPlugin:execute(1245): action=register
    11-09 20:17:11.670: V/GCMPlugin:execute(1245): data=[{“senderID”:”XXXXXXXXXX”,”ecb”:”GCM_Event”}]
    11-09 20:17:11.690: V/GCMPlugin:execute(1245): jo={“senderID”:”XXXXXXXXXX”,”ecb”:”GCM_Event”}
    11-09 20:17:11.690: V/GCMPlugin:execute(1245): ECB=GCM_Event senderID=XXXXXXXXXX
    11-09 20:17:11.700: V/GCMRegistrar(1245): Registering receiver
    11-09 20:17:11.710: D/GCMRegistrar(1245): resetting backoff for org.apache.cordova.example
    11-09 20:17:11.740: V/GCMRegistrar(1245): Registering app org.apache.cordova.example of senders XXXXXXXXXX
    11-09 20:17:11.760: V/GCMPlugin:execute(1245): GCMRegistrar.register called
    11-09 20:17:11.820: D/TilesManager(1245): Starting TG #0, 0x2a234580
    11-09 20:17:12.832: I/Choreographer(1245): Skipped 66 frames! The application may be doing too much work on its main thread.

  9. Dear Gonzalo Ayuso now i got registration id and i saved in database but stil when i am setting in your code my api key and registration Id that after return google server both values i set but still error showing

    print_r($pusher->getOutputAsArray());

    Array
    (
    [multicast_id] => 4.8474865209653E+18
    [success] => 0
    [failure] => 1
    [canonical_ids] => 0
    [results] => Array
    (
    [0] => Array
    (
    [error] => InvalidRegistration
    )

    )
    )

    now why its showing invalid registration because i have registration after implment push plugin so what the problem. if u want i will give u device id .

  10. There is problem i am saving registerid as a nvarchar(250) datatype and on my website there is a button when i am click i am running your code and finding error as i mentioned above.

    1. I’ve got a working application with this code right now. It’s working without any problem. Your problems look like that your aren’t using the correct registrationID (provided by phonegap/cordova when you run your applicatin) and your api key (provided by google using the google’s consolo). Please read the plugin documentation and follow the steps.

      1. thanx you are rite problem in reg id now notification working properly i thing more
        if i want to reverse this situation like i want to send notification from mobile to my website how it would be possible

      2. You need a different solution. You can perform a simple request to the server from the device and then trigger a websocket to alert the browser. Obviously you need to have your browser open with the properly url. You also can do it with Google Cloud Messaging for Chrome (http://developer.chrome.com/apps/cloudMessaging.html), but I’ve never play with it

  11. THANKS a lot, Mr. Ayuso!! I was trying a lot of other php backends, but always failing (the receiving), although it was working with the javascript “DevGirl” example.

    You saved me 2 days of research and work!! 🙂

  12. Works great. Thank you.
    Have a question is about phonegap(not related to server side). How to get registration status of device in phonegap pushplugin? I need to avoid re registering every time the app launched, But do that only after update/re-install

  13. I would suggest the service Puship.com, allowed me to configure my service to send notifications from PHP in a small time. It’s based on the pushplugin so it support the Online build for all platform

  14. hi i want to send the data on multiple gcm at the same type and i am having multiple register id also i am not getting the concept please help me it in Thank You

  15. Greate code, thx for sharing.

    I’m having a really bad time trying to make a download script to work inside webview. The problem is I can’t use the phonegap root features becouse I’m loading an external wordpress site in it. Do you know if there’s any way to make this possible?

    I’m trying to download a JPG file.

    1. With phonegap/cordava if you need to download something you need to use FileTransfer plugin. You can see one example here: https://gonzalo123.com/2014/07/28/upgrading-android-apps-outside-google-play-store-with-angularjs/

      In this post we download a apk file from an external server into device.

      Anyway if you are using an external site inside the webview your’ll have problems. especially if you follow links outside the root site. With SPA is simpler, but with traditional sites (such as wordpress) you will face problems. It’s possible to use phonegap plugins with an external site (inside a webview) you only need to include the cordova.js (and plugins) from the external site instead from the local build. You need to copy them by hand from local build to remote server and include the required files in your html.

  16. Hi Ayuso,

    I have a simple app containing text box and submit button. I need to send the message as push notification whenever i submit the button to all those whoever using my app. How can i achieve this.

    i have done upto this much.
    1) cordova create hello com.hello.test pushtest
    2) cd hello
    3) cordova platform add android
    4) cordova build android
    5) cordova plugin add C:\Users\emizr\Documents\PushPlugin-master\PushPlugin-master

    plugin added successfully…

    I don know how to proceed further. Could you please help me out in sending push notification on click of the submit button. ?

      1. Hi Ayuso,

        Thanks for the reply. I am unable to understand the coding thing what they have given. Could you explain me step by step. as i have told how much i have done. Could you spend me some valuable time to help me out in this.

        please

      1. Hello
        have you a tutorial on getting phone’s registration Ids and storing them to mysql databases?

        thanks

  17. Hi,
    I have used your code to send notifications. Before I tried PushApps and from their I am able to register the device and save the device token to database and use their provided API and loop the device tokens and push notifications to each device. Howeverr, I came to know that it isn’t free. So, while I was searching over internet, I came across and tried your code. I have run the code and I am able to recieve the notification. I mean, I am able to see the image of my app and name of the app. I am unable to recieve the message I push. Where am I going wrong. Please help.

  18. Hi Gonzalo,

    I have created a sample android app using phonegap build. Here I am implementing the push notification with the help of plugin and gcm.
    Here I am getting the correct device registration id. And then I am trying to send my phone a sample notification using a server side php script using following code.

    //request url
    $url = ‘https://android.googleapis.com/gcm/send’;

    //your api key
    $apiKey = ‘AIzaSyA2foUtzTp34b2VtI2Vfb_4U_KYSGQMVJI’;

    //registration ids
    $registrationIDs = array(‘APA91bHAnARblWioLReUbwbTSsDwWD1_Tz5NsU-Rrfa8SwFYWakbd3lWr5c8Ke9j4DhMlVliI9KNfW5olStgP-2iy1rRiaA1AlQgiC9eUc3_Kn3Njb808t9PN3DORU16-H_8FDFOxrsd’);

    //payload data
    $data = array(‘score’ => ‘1-0’, ‘scorer’ => ‘Ronaldo’, ‘time’ => ’44’);

    $fields = array(‘registration_ids’ => $registrationIDs,
    ‘data’ => $data);

    //http header
    $headers = array(‘Authorization: key=’ . $apiKey,
    ‘Content-Type: application/json’);

    //curl connection
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    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($fields));

    $result = curl_exec($ch);

    curl_close($ch);

    echo $result;

    When I call this script, I am getting response as
    {“multicast_id”:some number,”success”:1,”failure:0″,”canonical_ids”:0,”results”:[{“message_id”:”some id”}]}

    The issue is though the call is success, But I am not getting the notification in the notification tray instead getting above message.

    Can you tell me why am I not getting the notification?
    If I am not wrong I think there is some issue with my client side code. But what I am not able to understand.

    1. Google say that push notification have been sent to the device (success:1). You must ensure your device has internet access. Close your application in the device and send again the notification.

    2. aditya could you provide me your email id, I have working example with me, i can mail you the project. It is a small project focused on push notification through phonegap..

  19. Hey there! I’d love to use it in a project but you didin’t put a license anywhere, so legally I can’t use 😦

  20. Hi Gonzalo,

    I’m sending notifications properly to my Android, but I’m only getting a single line notification. Do you know how to show a multiple lines ? Cheers.

  21. I am new to android … and also in Intel XDK environment.

    Gentlemen supporters, kindly guide me on the questions below:

    1-I want to develop an app for android, which from a text box (text area or imput button) the user to inform your contact

    or a fact or even a complaint, this is sent to a specific e-mail, you see? as a kind of FEEDBACK. It could even be sent

    also to a specific whatsapp, but do not know what would be the most interesting, quick and efficient resolution of

    technical view point.

    2-I have researched a lot about cord-plugins-email-compose, that is, within the Intel XDK environment; I did several

    tests and examples collected from the internet, but do not work. On the other hand, outshines in my view the issue of e-

    mail, domain on android, do not know how this. For I see several apps, same with many such resources, forms, sending

    data, etc. But I’m having a hard time understanding these things.

    3-In a web environment this is all understandable to me. Many years ago, I got to do a few simple things in PHP and Mysql

    … as the situation I described above … made a page in HTML, logging suggestions and invoking a script on the server

    side PHP that I sent these records to a specific email. I stayed this page in cloud, remember that the (localweb) and

    localweb server had the resources to support PHP, Mysql. To host this page on the server, I had to create a domain in

    registro.BR and the service to send form data to an e-mail functioned normally. So I wanted to take this same solution

    … the same idea … ie the web server environment for smartphones environment, android. You see? Finally, develop a

    simple app that the user could file a claim (form – text area, or INPUT button) and this was sent to a specific e-mail or

    even a whatsapp. A solution type Push notification.

    questions:

    1) I have almost given up the cord-plugins-email-compose, however, you can guide me more about this plugin and how to set

    up properly?
    2-Where sets my account email in-cord plug-email-compose?
    3) Can I send data from a form (text area) to integrate Intel XDK with PHP? (Ie, because in PHP, I know how to nviar and

    e-mail)
    3) To host app, which server would indicate me?
    4) Are there any free or paid server to send the APK and test, ie I could download and test the App on my phone?
    5) To host my APP APK or on free or paid server, I would have to necessarily create have a domain? email account?
    6) Can demontrar me or send me an APP / APK to record a message, or text, or subject (text area or INPUT button) and

    internally APP feature to send this message to an e-mail?
    7) I enjoyed the Intel XDK environment, but I would indicate another similar tool, given the complexity of dealing with

    e-mail?

    Thanks for the clarification.
    Thank you.
    Jorge F.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.