Firebase Cloud Messaging (FCM) is the new version of GCM. We will see here how to send push notification from PHP server to android app client in short time and simple way with single device id. Developers requires a little knowledge to understand following code. I will discuss here only important coding modules and functions.
It has more features than GCM like Analytics, Firebase Remote Config, Easy Implementation, Cross-platform support, Web Push support. We strongly recommend that you migrate to Firebase Cloud Messaging Platform . Google recommends upgrading from GCM to FCM in their APIs for Android. Initially many developers gets panic to migrate from GCM to FCM.
See the following coding snippet of important files and functions
MainActivity.java :
There is no change in MainActivity.java file.
AndroidManifest.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="in.nfluence.fcm" > <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyInstanceIDListenerService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service> <service android:name=".MyFcmListenerService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> </application> </manifest> |
MyInstanceIDListenerService.java:
Called if InstanceID token is updated. This may occur if the security of the previous token had been compromised. Note that this is also called when the InstanceID token is initially generated, so this is where you retrieve the token.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package in.nfluence.fcm; import android.util.Log; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceIdService; public class MyInstanceIDListenerService extends FirebaseInstanceIdService { // [START refresh_token] @Override public void onTokenRefresh() { // Get updated InstanceID token. String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d("Token FCM", "Refreshed token: " + refreshedToken); // TODO: Implement this method to send any registration to your app's servers. sendRegistrationToServer(refreshedToken); } private void sendRegistrationToServer(String refreshedToken) { } } |
MyFcmListenerService.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
package in.nfluence.fcm; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.TaskStackBuilder; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.NotificationCompat; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; import java.util.Calendar; import java.util.Map; public class MyFcmListenerService extends FirebaseMessagingService { private static final String TAG = "MyFcmListenerService"; @Override public void onMessageReceived(RemoteMessage message){ //String from = message.getFrom(); Map data = message.getData(); String messagenote = data.get("message").toString(); String title = data.get("title").toString(); String tickerText = data.get("tickerText").toString(); String subtitle = data.get("subtitle").toString(); long when= Calendar.getInstance().getTimeInMillis(); NotificationManager notificationManager= (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); Intent notificationIntent = new Intent(this, MainActivity.class); Bundle bundle = new Bundle(); bundle.putString("ms", messagenote); notificationIntent.putExtras(bundle); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); notificationIntent.setData(Uri.parse("content://" + when)); PendingIntent intent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT); startActivity(notificationIntent); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.mipmap.icon) .setContentTitle(title) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) .setTicker(tickerText) .setSubText(subtitle) .setContentIntent(intent) .setAutoCancel(true) .setContentText(messagenote); notificationManager.notify((int)when, mBuilder.build()); } } |
changes in build.gradle (Module:app):
Here you require only change in dependencies :
1 2 3 4 5 6 7 8 9 |
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:24.+' compile 'com.android.support:design:24.+' compile 'com.google.firebase:firebase-core:9.8.0' compile 'com.google.firebase:firebase-messaging:9.8.0' } apply plugin: 'com.google.gms.google-services' |
dependencies in build.grandle(Project: Project name):
1 2 3 4 5 |
dependencies { classpath 'com.android.tools.build:gradle:1.5.0' classpath 'com.google.gms:google-services:3.0.0' classpath 'com.android.tools.build:gradle:2.1.0' } |
google-services.json :
This file contains developer authentication credentials and configuration settings, which is needed to verify while connecting with GoogleApiClient. You have to put it under root directory of the app i.e under ProjectName/app/. Though your service is working fine with your test device as it is detecting your developer account but after releasing your app in public, it will not work without the json file. So don’t delete it. Create your FCM project here and download the google-services.json file.
Here it is sample look of google-services.json:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
{ "project_info": { "project_number": "***********", "firebase_url": "************", "project_id": "***********", "storage_bucket": "**********" }, "client": [ { "client_info": { "mobilesdk_app_id": "***************************", "android_client_info": { "package_name": "in.nfluence.fcm" } }, "oauth_client": [ { "client_id": "***********-*******************.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { "current_key": "****************************" // this is your API_ACCESS_KEY_IN_PHP } ], "services": { "analytics_service": { "status": 1 }, "appinvite_service": { "status": 1, "other_platform_oauth_client": [] }, "ads_service": { "status": 2 } } } ], "configuration_version": "1" } |
Pushnote.php:
Enter FCM refresh token manually and refresh this php page and check your app receives notification or not. If want to know how to insert FCM refresh token into database then see this post Android Insert Data to MySQL Database Using PHP (Android , MySQL , PHP , PDO)
In following code I have mentioned ‘API_ACCESS_KEY’ which is provided by google. You can create your FCM Project here and get API_ACCESS_KEY.
The variable $registrationIds is android device id. Add your ids in array.
The $msg is your notification format . You can custom as per your choice.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<?php // API access key from Google API's Console define( 'API_ACCESS_KEY', '***********************' ); // get this KEY from google //define( 'API_ACCESS_KEY', '**********' );// may required for client app //$registrationIds = array( $_GET['id'] ); // if u using GET-POST method then try this $registrationIds = array('afjalasdfdfafa_ENTER_YOUR_DEVICE_ID_AND_REFRESH_THIS_PAGE'); //insert device id here from android studio logcat search there 'Refreshed Token' // prep the bundle $msg = array ( 'message' => 'here is a message. message', 'title' => 'This is a title. title', 'subtitle' => 'This is a subtitle. subtitle', 'tickerText' => 'Ticker text here...Ticker text here...Ticker text here', 'vibrate' => 1, 'sound' => 1, 'largeIcon' => 'large_icon', 'smallIcon' => 'small_icon' ); $fields = array ( 'registration_ids' => $registrationIds, 'data' => $msg ); $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( $fields ) ); $result = curl_exec($ch ); curl_close( $ch ); echo $result; $canonical_ids_count = $result->canonical_ids; echo 'before if:'.$canonical_ids_count; print_r($canonical_ids_count); if($canonical_ids_count){ //update your DB by replacing the registration id with //the canonical id(new registration id) echo 'IN if'.$canonical_ids_count; } ?> |
Output:
Understand above code and if you facing any problem comment bellow.