214

Update: GCM is deprecated, use FCM

How can I integrate the new Google Cloud Messaging in a PHP backend?

Jacks
  • 735
  • 1
  • 4
  • 16
user1488243
  • 2,297
  • 4
  • 12
  • 7
  • http://www.sherif.mobi/2012/07/gcm-php-push-server.html – Sherif elKhatib Oct 23 '12 at 10:46
  • 4
    I've written a small OOP-library with an implementation of GCM-server. Hope it will help someone :) Check it on GitHub - https://github.com/CodeMonkeysRu/GCMMessage – iVariable Apr 22 '13 at 08:36
  • 1
    @HelmiB: I tried your code on website, it executes without any error, but the $result is empty. Also the message won't deliver. Please help me. I'm in a really need of it. – user2064667 Sep 12 '13 at 07:51
  • My fork of GCMMessage support exponential backup which is mandatory for using Google's API. It uses a redis server for queuing messages and supports the new endpoint as well as iOS: https://github.com/stevetauber/php-gcm-queue – Steve Tauber Jan 18 '16 at 12:05
  • Its very simple, all you need is just an app server, GCM server and an app hosting that service. Refer this example. Here localhost acts as app server http://www.feelzdroid.com/2016/02/android-google-cloud-messaging-push-notifications-gcm-tutorial.html – Naruto Feb 07 '16 at 11:36

13 Answers13

237

This code will send a GCM message to multiple registration IDs via PHP CURL.

// Payload data you want to send to Android device(s)
// (it will be accessible via intent extras)    
$data = array('message' => 'Hello World!');

// The recipient registration tokens for this notification
// https://developer.android.com/google/gcm/    
$ids = array('abc', 'def');

// Send push notification via Google Cloud Messaging
sendPushNotification($data, $ids);

function sendPushNotification($data, $ids) {
    // Insert real GCM API key from the Google APIs Console
    // https://code.google.com/apis/console/        
    $apiKey = 'abc';

    // Set POST request body
    $post = array(
                    'registration_ids'  => $ids,
                    'data'              => $data,
                 );

    // Set CURL request headers 
    $headers = array( 
                        'Authorization: key=' . $apiKey,
                        'Content-Type: application/json'
                    );

    // Initialize curl handle       
    $ch = curl_init();

    // Set URL to GCM push endpoint     
    curl_setopt($ch, CURLOPT_URL, 'https://gcm-http.googleapis.com/gcm/send');

    // Set request method to POST       
    curl_setopt($ch, CURLOPT_POST, true);

    // Set custom request headers       
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    // Get the response back as string instead of printing it       
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // Set JSON post data
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post));

    // Actually send the request    
    $result = curl_exec($ch);

    // Handle errors
    if (curl_errno($ch)) {
        echo 'GCM error: ' . curl_error($ch);
    }

    // Close curl handle
    curl_close($ch);

    // Debug GCM response       
    echo $result;
}
Elad Nava
  • 6,524
  • 2
  • 36
  • 59
  • for me both "Key for server apps" & "Key for browser apps" works as long as i dont add any filter in ip/referer – Vjy Jul 01 '12 at 13:05
  • 3
    it's almost working here, but i dont receive any message on the phone. I want to debug it, but i dont know why my $result is always empty... – Bertrand Jul 05 '12 at 11:49
  • Nice find! Yeah, if your server failed to verify Google's SSL the function will fail. Adding the code you mentioned bypasses verification. – Elad Nava Jul 12 '12 at 19:55
  • 9
    Where can i get registration id's? – Seshu Vinay Sep 03 '12 at 09:27
  • Please read the entire GCM documentation to find out how you can send the device registration ID from your app to your third-party server. – Elad Nava Sep 08 '12 at 12:07
  • Refer to the codes above, how can someone obtain "client registration IDs"? Thanks! – Ham Sep 20 '12 at 08:35
  • Hi Elad, I tried your code. It shows a success message but the message is not displayed on my device. What might be the problem? – Ramaraju.d Oct 11 '12 at 09:33
  • Did you correctly implement the broadcast receiver code in your Android application? You can place a breakpoint on this code and it should fire when you try sending a push message via this script. If it doesn't fire, you did not correctly implement the broadcast receiver or the manifest code – Elad Nava Oct 11 '12 at 13:12
  • 1
    Worked for me. The only things I'd edit in the code above are : 1. Remove the following comments: // Replace with real BROWSER API key from Google APIs and replace with // Replace with real 'key for server apps' frmo Google APIs 2. Add the following two lines: curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); – justadev Nov 16 '12 at 19:27
  • 6
    Thanks for this answer! I rolled it up into a PHP object framework if this is useful to anybody: https://github.com/kaiesh/GCM_PHP – Kaiesh Dec 20 '12 at 11:37
  • Works perfect in my case, but only with the server key. I've tried with browser key and error 401 comes up. – Neonamu Feb 20 '13 at 12:23
  • my device has registered successfully and I have my device regId also. what is the expected result from the gcm server when i send a broadcast? I am not getting any response - its null! also the device doesnt show up any message. – shiladitya Mar 10 '13 at 07:01
  • 6
    @Sit Disabling SSL certificate checks is ALWAYS a bad idea. If your server can't verify a SSL certificate, use this technique to tell cURL what certificate to expect: http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/ or force cURL to use the latest cacert.pem from the cURL website using something like this: https://gist.github.com/gboudreau/5206966 – Guillaume Boudreau Mar 20 '13 at 18:04
  • I am getting 401 error for both server key and browser key. What can be the problem? tried a lot no clue. – sampopes Sep 24 '14 at 20:17
  • Try using a different Google account. Maybe it was a temporary problem that will resolve itself when you retry. – Elad Nava Sep 30 '14 at 13:34
  • 4
    This helped: `curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );` – zeusstl Feb 09 '15 at 15:59
  • Thanks @zeusstl, I had been struggling with this and realised my ip being sent was v6, not the v4 as i had allowed in the GCM console – Ashley Mar 28 '15 at 14:45
  • This fails when 1,000 > devices are given (http://developer.android.com/training/cloudsync/gcm.html) – Maurício Giordano Jun 01 '15 at 20:28
  • Ironically, this seems to break on Google App Engine where it seems all Google hosted urls are blocked by cURL – N S Apr 14 '16 at 22:50
  • @Cal S, check out http://stackoverflow.com/questions/17977712/php-gcm-appengine for sample PHP code that sends a push notification through GCM on Google App Engine. – Elad Nava Apr 15 '16 at 13:21
  • I tried this code but i'm getting json parse error. – sharon May 25 '16 at 07:48
  • What is the exact error you are getting? Sometimes PHP has trouble parsing JSON that contains certain "foreign" characters. – Elad Nava May 25 '16 at 09:01
  • Check the PHP JSON error by invoking `json_last_error()`: http://php.net/manual/en/function.json-last-error.php – Elad Nava May 25 '16 at 09:32
  • Can i use the same code to send notification to IOS device. – Harendra Singh Sep 03 '16 at 13:22
  • Absolutely! Make sure to specify notification fields as documented here: https://developers.google.com/cloud-messaging/http-server-ref – Elad Nava Sep 05 '16 at 10:47
35
<?php
    // Replace with the real server API key from Google APIs
    $apiKey = "your api key";

    // Replace with the real client registration IDs
    $registrationIDs = array( "reg id1","reg id2");

    // Message to be sent
    $message = "hi Shailesh";

    // Set POST variables
    $url = 'https://android.googleapis.com/gcm/send';

    $fields = array(
        'registration_ids' => $registrationIDs,
        'data' => array( "message" => $message ),
    );
    $headers = array(
        'Authorization: key=' . $apiKey,
        'Content-Type: application/json'
    );

    // Open connection
    $ch = curl_init();

    // Set the URL, number of POST vars, POST data
    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_POSTFIELDS, json_encode( $fields));

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    // curl_setopt($ch, CURLOPT_POST, true);
    // curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $fields));

    // Execute post
    $result = curl_exec($ch);

    // Close connection
    curl_close($ch);
    echo $result;
    //print_r($result);
    //var_dump($result);
?>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Shailesh Giri
  • 359
  • 2
  • 3
  • 3
    Hi Shailesh Giri, its working fine by using **Browser key**,but in case of Server key, it shows **Unauthorized Error 401**. Can you help me please. – Sushil Kandola Sep 27 '12 at 10:31
  • what is the expected result from the server? I am not getting any response! also the device doesnt show up any message. – shiladitya Mar 10 '13 at 06:50
  • 3
    `curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);` is a big no-no. If, for some reason, your server running this PHP code can't verify the SSL certificate used by Google's servers, you can tell cURL what to verify with. Example: http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/ – Guillaume Boudreau Mar 20 '13 at 17:52
19

It's easy to do. The cURL code that's on the page that Elad Nava has put here works. Elad has commented about the error he's receiving.

String describing an error that occurred while processing the message for that recipient. The possible values are the same as documented in the above table, plus "Unavailable" (meaning GCM servers were busy and could not process the message for that particular recipient, so it could be retried).

I've got a service set up already that seems to be working (ish), and so far all I've had back are unavailable returns from Google. More than likely this will change soon.

To answer the question, use PHP, make sure the Zend Framework is in your include path, and use this code:

<?php
    ini_set('display_errors',1);
    include"Zend/Loader/Autoloader.php";
    Zend_Loader_Autoloader::getInstance();

    $url = 'https://android.googleapis.com/gcm/send';
    $serverApiKey = "YOUR API KEY AS GENERATED IN API CONSOLE";
    $reg = "DEVICE REGISTRATION ID";

    $data = array(
            'registration_ids' => array($reg),
            'data' => array('yourname' => 'Joe Bloggs')
    );

    print(json_encode($data));

    $client = new Zend_Http_Client($url);
    $client->setMethod('POST');
    $client->setHeaders(array("Content-Type" => "application/json", "Authorization" => "key=" . $serverApiKey));
    $client->setRawData(json_encode($data));
    $request = $client->request('POST');
    $body = $request->getBody();
    $headers = $request->getHeaders();
    print("<xmp>");
    var_dump($body);
    var_dump($headers);

And there we have it. A working (it will work soon) example of using Googles new GCM in Zend Framework PHP.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Roger Thomas
  • 665
  • 4
  • 15
  • 9
    MASSIVE UPDATE! Apparently using an API Key set with IP Restriction fails to work. I just swapped my API Key in the Server side to use the Key in the API Console called 'Key for browser apps (with referers)' And guess what! It went through. Here's what I had returned: {"multicast_id":8466657113827057558,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1341067903035991%921c249a66d6cf16"}]} – Roger Thomas Jun 30 '12 at 14:52
  • 1
    Its on and off now. I've got about 3500 messages a day going through it and so far no problems to report. – Roger Thomas Jul 23 '12 at 18:17
  • +1 Elad .. you have to use the BROWSER application API key for SERVER applications! Thanks Google, really helpful FAIL there :( (wasted many hours) – Jonny Nott Feb 04 '14 at 00:04
13

After searching for a long time finally I am able to figure out what I exactly needed, Connecting to the GCM using PHP as a server side scripting language, The following tutorial will give us a clear idea of how to setup everything we need to get started with GCM

Android Push Notifications using Google Cloud Messaging (GCM), PHP and MySQL

yogasaikrishna
  • 139
  • 2
  • 4
10

I actually have this working now in a branch in my Zend_Mobile tree: https://github.com/mwillbanks/Zend_Mobile/tree/feature/gcm

This will be released with ZF 1.12, however, it should give you some great examples on how to do this.

Here is a quick demo on how it would work....

<?php
require_once 'Zend/Mobile/Push/Gcm.php';
require_once 'Zend/Mobile/Push/Message/Gcm.php';

$message = new Zend_Mobile_Push_Message_Gcm();
$message->setId(time());
$message->addToken('ABCDEF0123456789');
$message->setData(array(
    'foo' => 'bar',
    'bar' => 'foo',
));

$gcm = new Zend_Mobile_Push_Gcm();
$gcm->setApiKey('MYAPIKEY');

$response = false;

try {
    $response = $gcm->send($message);
} catch (Zend_Mobile_Push_Exception $e) {
    // all other exceptions only require action to be sent or implementation of exponential backoff.
    die($e->getMessage());
}

// handle all errors and registration_id's
foreach ($response->getResults() as $k => $v) {
    if ($v['registration_id']) {
        printf("%s has a new registration id of: %s\r\n", $k, $v['registration_id']);
    }
    if ($v['error']) {
        printf("%s had an error of: %s\r\n", $k, $v['error']);
    }
    if ($v['message_id']) {
        printf("%s was successfully sent the message, message id is: %s", $k, $v['message_id']);
    }
}
mwillbanks
  • 991
  • 1
  • 7
  • 10
  • 1
    Ok! This is good. but how can I get the token of the users. I guess you are using tokens as registrationIDs. In my Android app, what will be the server URL? – tasomaniac Jul 06 '12 at 16:06
  • Yes tokens are the registration id's; this is specifically because the library attempts to remain somewhat abstract since it also implements APNS and MPNS. The server URL is whatever you end up making; this simply provides the glue for sending, you will need to write an area where you would post the registration id to and save it somewhere. From there you can utilize the above code to actually send a push notification to the app. – mwillbanks Jul 09 '12 at 12:54
6

Also you can try this piece of code, source:

<?php
    define("GOOGLE_API_KEY", "AIzaSyCJiVkatisdQ44rEM353PFGbia29mBVscA");
    define("GOOGLE_GCM_URL", "https://android.googleapis.com/gcm/send");

    function send_gcm_notify($reg_id, $message) {
        $fields = array(
            'registration_ids'  => array( $reg_id ),
            'data'              => array( "message" => $message ),
        );

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

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, GOOGLE_GCM_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);
        if ($result === FALSE) {
            die('Problem occurred: ' . curl_error($ch));
        }

        curl_close($ch);
        echo $result;
    }

    $reg_id = "APA91bHuSGES.....nn5pWrrSz0dV63pg";
    $msg = "Google Cloud Messaging working well";

    send_gcm_notify($reg_id, $msg);
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
dexxtr
  • 468
  • 1
  • 5
  • 8
  • Your code shows error "Problem occurred: Failed to connect to 74.125.142.95: Permission denied". Whats is the problem? – user2064667 Sep 12 '13 at 06:40
6

A lot of the tutorials are outdated, and even the current code doesn't account for when device registration_ids are updated or devices unregister. If those items go unchecked, it will eventually cause issues that prevent messages from being received. http://forum.loungekatt.com/viewtopic.php?t=63#p181

Abandoned Cart
  • 3,230
  • 29
  • 32
4
<?php

function sendMessageToPhone($deviceToken, $collapseKey, $messageText, $yourKey) {    
    echo "DeviceToken:".$deviceToken."Key:".$collapseKey."Message:".$messageText
            ."API Key:".$yourKey."Response"."<br/>";

    $headers = array('Authorization:key=' . $yourKey);    
    $data = array(    
        'registration_id' => $deviceToken,          
        'collapse_key' => $collapseKey,
        'data.message' => $messageText);  
    $ch = curl_init();    

    curl_setopt($ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send");    
    if ($headers)    
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);    
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);    
    curl_setopt($ch, CURLOPT_POST, true);    
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);    
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);    

    $response = curl_exec($ch);    
    var_dump($response);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);    
    if (curl_errno($ch)) {
        return false;
    }    
    if ($httpCode != 200) {
        return false;
    }    
    curl_close($ch);    
    return $response;    
}  

$yourKey = "YOURKEY";
$deviceToken = "REGISTERED_ID";
$collapseKey = "COLLAPSE_KEY";
$messageText = "MESSAGE";
echo sendMessageToPhone($deviceToken, $collapseKey, $messageText, $yourKey);
?>

In above script just change :

"YOURKEY" to API key to Server Key of API console.
"REGISTERED_ID" with your device's registration ID
"COLLAPSE_KEY" with key which you required
"MESSAGE" with message which you want to send

Let me know if you are getting any problem in this I am able to get notification successfully using the same script.

Shahzad
  • 2,443
  • 6
  • 21
  • 31
Ajit
  • 214
  • 1
  • 6
2

You can use this PHP library available on packagist:

https://github.com/CoreProc/gcm-php

After installing it you can do this:

$gcmClient = new GcmClient('your-gcm-api-key-here');

$message = new Message($gcmClient);

$message->addRegistrationId('xxxxxxxxxx');
$message->setData([
    'title' => 'Sample Push Notification',
    'message' => 'This is a test push notification using Google Cloud Messaging'
]);

try {

    $response = $message->send();

    // The send() method returns a Response object
    print_r($response);

} catch (Exception $exception) {

    echo 'uh-oh: ' . $exception->getMessage();

}
chrisbjr
  • 628
  • 4
  • 10
0

Here's a library I forked from CodeMonkeysRU.

The reason I forked was because Google requires exponential backoff. I use a redis server to queue messages and resend after a set time.

I've also updated it to support iOS.

https://github.com/stevetauber/php-gcm-queue

Steve Tauber
  • 7,905
  • 5
  • 37
  • 44
  • Hello could you please point me out to the changes made for iOS, I don't really see anything special compare to the original library. – fralbo May 12 '16 at 08:34
  • @2ndGAB the primary reason I forked was the exponential backoff. As for the iOS changes, you can read about them here: https://developers.google.com/cloud-messaging/http-server-ref#notification-payload-support – Steve Tauber May 14 '16 at 16:25
0

Here is android code for PHP code of above posted by @Elad Nava

MainActivity.java (Launcher Activity)

public class MainActivity extends AppCompatActivity {
    String PROJECT_NUMBER="your project number/sender id";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        GCMClientManager pushClientManager = new GCMClientManager(this, PROJECT_NUMBER);
        pushClientManager.registerIfNeeded(new GCMClientManager.RegistrationCompletedHandler() {
            @Override
            public void onSuccess(String registrationId, boolean isNewRegistration) {

                Log.d("Registration id", registrationId);
                //send this registrationId to your server
            }

            @Override
            public void onFailure(String ex) {
                super.onFailure(ex);
            }
        });
    }
}

GCMClientManager.java

public class GCMClientManager {
    // Constants
    public static final String TAG = "GCMClientManager";
    public static final String EXTRA_MESSAGE = "message";
    public static final String PROPERTY_REG_ID = "your sender id";
    private static final String PROPERTY_APP_VERSION = "appVersion";
    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    // Member variables
    private GoogleCloudMessaging gcm;
    private String regid;
    private String projectNumber;
    private Activity activity;
    public GCMClientManager(Activity activity, String projectNumber) {
        this.activity = activity;
        this.projectNumber = projectNumber;
        this.gcm = GoogleCloudMessaging.getInstance(activity);
    }
    /**
     * @return Application's version code from the {@code PackageManager}.
     */
    private static int getAppVersion(Context context) {
        try {
            PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
        } catch (NameNotFoundException e) {
            // should never happen
            throw new RuntimeException("Could not get package name: " + e);
        }
    }
    // Register if needed or fetch from local store
    public void registerIfNeeded(final RegistrationCompletedHandler handler) {
        if (checkPlayServices()) {
            regid = getRegistrationId(getContext());
            if (regid.isEmpty()) {
                registerInBackground(handler);
            } else { // got id from cache
                Log.i(TAG, regid);
                handler.onSuccess(regid, false);
            }
        } else { // no play services
            Log.i(TAG, "No valid Google Play Services APK found.");
        }
    }
    /**
     * Registers the application with GCM servers asynchronously.
     * <p>
     * Stores the registration ID and app versionCode in the application's
     * shared preferences.
     */
    private void registerInBackground(final RegistrationCompletedHandler handler) {
        new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                try {
                    if (gcm == null) {
                        gcm = GoogleCloudMessaging.getInstance(getContext());
                    }
                    InstanceID instanceID = InstanceID.getInstance(getContext());
                    regid = instanceID.getToken(projectNumber, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
                    Log.i(TAG, regid);
                    // Persist the regID - no need to register again.
                    storeRegistrationId(getContext(), regid);
                } catch (IOException ex) {
                    // If there is an error, don't just keep trying to register.
                    // Require the user to click a button again, or perform
                    // exponential back-off.
                    handler.onFailure("Error :" + ex.getMessage());
                }
                return regid;
            }
            @Override
            protected void onPostExecute(String regId) {
                if (regId != null) {
                    handler.onSuccess(regId, true);
                }
            }
        }.execute(null, null, null);
    }
    /**
     * Gets the current registration ID for application on GCM service.
     * <p>
     * If result is empty, the app needs to register.
     *
     * @return registration ID, or empty string if there is no existing
     *     registration ID.
     */
    private String getRegistrationId(Context context) {
        final SharedPreferences prefs = getGCMPreferences(context);
        String registrationId = prefs.getString(PROPERTY_REG_ID, "");
        if (registrationId.isEmpty()) {
            Log.i(TAG, "Registration not found.");
            return "";
        }
        // Check if app was updated; if so, it must clear the registration ID
        // since the existing regID is not guaranteed to work with the new
        // app version.
        int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
        int currentVersion = getAppVersion(context);
        if (registeredVersion != currentVersion) {
            Log.i(TAG, "App version changed.");
            return "";
        }
        return registrationId;
    }
    /**
     * Stores the registration ID and app versionCode in the application's
     * {@code SharedPreferences}.
     *
     * @param context application's context.
     * @param regId registration ID
     */
    private void storeRegistrationId(Context context, String regId) {
        final SharedPreferences prefs = getGCMPreferences(context);
        int appVersion = getAppVersion(context);
        Log.i(TAG, "Saving regId on app version " + appVersion);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(PROPERTY_REG_ID, regId);
        editor.putInt(PROPERTY_APP_VERSION, appVersion);
        editor.commit();
    }
    private SharedPreferences getGCMPreferences(Context context) {
        // This sample app persists the registration ID in shared preferences, but
        // how you store the regID in your app is up to you.
        return getContext().getSharedPreferences(context.getPackageName(),
                Context.MODE_PRIVATE);
    }
    /**
     * Check the device to make sure it has the Google Play Services APK. If
     * it doesn't, display a dialog that allows users to download the APK from
     * the Google Play Store or enable it in the device's system settings.
     */
    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getContext());
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.i(TAG, "This device is not supported.");
            }
            return false;
        }
        return true;
    }
    private Context getContext() {
        return activity;
    }
    private Activity getActivity() {
        return activity;
    }
    public static abstract class RegistrationCompletedHandler {
        public abstract void onSuccess(String registrationId, boolean isNewRegistration);
        public void onFailure(String ex) {
            // If there is an error, don't just keep trying to register.
            // Require the user to click a button again, or perform
            // exponential back-off.
            Log.e(TAG, ex);
        }
    }
}

PushNotificationService.java (Notification generator)

public class PushNotificationService extends GcmListenerService{

    public static int MESSAGE_NOTIFICATION_ID = 100;

    @Override
    public void onMessageReceived(String from, Bundle data) {
        String message = data.getString("message");
        sendNotification("Hi-"+message, "My App sent you a message");
    }

    private void sendNotification(String title, String body) {
        Context context = getBaseContext();
        NotificationCompat.Builder mBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(context)
                .setSmallIcon(R.mipmap.ic_launcher).setContentTitle(title)
                .setContentText(body);
        NotificationManager mNotificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(MESSAGE_NOTIFICATION_ID, mBuilder.build());
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.example.gcm.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme" >
    <activity android:name=".MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service
        android:name=".PushNotificationService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>

    <receiver
        android:name="com.google.android.gms.gcm.GcmReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="package.gcmdemo" />
        </intent-filter>
    </receiver>
</application>

Akshay Paliwal
  • 3,050
  • 2
  • 35
  • 42
0

use this

 function pnstest(){

                $data = array('post_id'=>'12345','title'=>'A Blog post', 'message' =>'test msg');

                $url = 'https://fcm.googleapis.com/fcm/send';

                $server_key = 'AIzaSyDVpDdS7EyNgMUpoZV6sI2p-cG';

                $target ='fO3JGJw4CXI:APA91bFKvHv8wzZ05w2JQSor6D8lFvEGE_jHZGDAKzFmKWc73LABnumtRosWuJx--I4SoyF1XQ4w01P77MKft33grAPhA8g-wuBPZTgmgttaC9U4S3uCHjdDn5c3YHAnBF3H';

                $fields = array();
                $fields['data'] = $data;
                if(is_array($target)){
                    $fields['registration_ids'] = $target;
                }else{
                    $fields['to'] = $target;
                }

                //header with content_type api key
                $headers = array(
                    'Content-Type:application/json',
                  'Authorization:key='.$server_key
                );

                $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_VERIFYHOST, 0);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
                $result = curl_exec($ch);
                if ($result === FALSE) {
                    die('FCM Send Error: ' . curl_error($ch));
                }
                curl_close($ch);
                return $result;

}
Rajkumar Kumawat
  • 292
  • 2
  • 11
0

I know this is a late Answer, but it may be useful for those who wants to develop similar apps with current FCM format (GCM has been deprecated).
The following PHP code has been used to send topic-wise podcast. All the apps registered with the mentioned channel/topis would receive this Push Notification.

<?php

try{
$fcm_token = 'your fcm token';
$service_url = 'https://fcm.googleapis.com/fcm/send';
$channel = '/topics/'.$adminChannel;
echo $channel.'</br>';
      $curl_post_body = array('to' => $channel,
        'content_available' => true,
        'notification' => array('click_action' => 'action_open',
                            'body'=> $contentTitle,
                            'title'=>'Title '.$contentCurrentCat. ' Updates' ,
                            'message'=>'44'),
        'data'=> array('click_action' => 'action_open',
                            'body'=>'test',
                            'title'=>'test',
                            'message'=>$catTitleId));

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

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $service_url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($curl_post_body));

    $result = curl_exec($ch);
    if ($result === FALSE) {
        die('FCM Send Error: ' . curl_error($ch));
        echo 'failure';
    }else{

    echo 'success' .$result;
    }
    curl_close($ch);
    return $result;

}
catch(Exception $e){

    echo 'Message: ' .$e->getMessage();
}
?>
Jacks
  • 735
  • 1
  • 4
  • 16