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

About these ads

About Gonzalo Ayuso

Web Architect specialized in Open Source technologies. PHP, Python, JQuery, Dojo, PostgreSQL, CouchDB and node.js but always learning.

Posted on August 5, 2013, in android, phonegap, php, Technology and tagged , , , . Bookmark the permalink. 36 Comments.

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

  2. Hi there Mr Ayuso,can you perhaps share how to implement this on the actual native project(in this case on my HTML and Javascript phonegap project) thanks alot…

  3. 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

  4. Hi there

    thanks for the info, but, how can we know the device id?

    $regId = “device reg ID”;

    Is something you get when the user installed the app?

    thanks

  5. 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?

  6. 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.

  7. qazi wajihurrehman

    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

    • 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

      • qazi wajihurrehman

        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.

      • 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)

      • qazi wajihurrehman

        last thing how to register push notifications in app.

  8. qazi wajihurrehman

    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

    • 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

      • qazi wajihurrehman

        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.

      • qazi wajihurrehman

        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

  9. qazi wajihurrehman

    as well as showing me google cloud messaging depreceated so what can i do now.

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

  10. qazi wajihurrehman

    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.

  11. qazi wajihurrehman

    what will process or setting for C2DM.

  12. qazi wajihurrehman

    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.

  13. qazi wajihurrehman

    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 .

  14. qazi wajihurrehman

    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.

    • 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.

      • qazi wajihurrehman

        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

      • 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

  15. 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!! :)

  16. 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

  1. Pingback: Дайджест интересных новостей и материалов из мира PHP за последние две недели (29.07.2013 — 11.08.2013) | Juds

  2. Pingback: Multiple Phonegap Push Notifications in the Android’s status bar | Gonzalo Ayuso | Web Architect

  3. Pingback: Enviando notificações push a partir do PHP para aplicações phonegap no Android | iMasters

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 972 other followers

%d bloggers like this: