Tuesday 20 March 2018

Push Notification example using firebase cloud messaging in android


Push Notification example using firebase cloud messaging in android



Firebase is a mobile and web-application development platform. It helps to develop app easier. It also combines analytics, database, authentication, storage , hosting, crashing reports etc. Before release of Firebase, we used Google cloud messaging service(GCM) for notification. Google introduced about firebase cloud messaging in Google I/O 2016 and rapidly growing up users usage. FCM having a lot of amazing features for mobile app developers. Compare to GCM, FCM is much more friendly because you don’t even need to see any of the server code imvolved.  

Before going to implementation, we need to set-up project details inside firebase console. 
Step1: First login into firebase console(https://firebase.google.com/). 
Step2: Then click on Add project, a pop-up dialog will appear, you need to provide project-name and country. After that click on create project. 



After creating project, inside project overview, click on ‘Add Firebase to your android app’.



Now you need to provide your app package name and as of now not providing app-nickname and signing certificate. 



Than click on register-app. Now you will see google-services.json file, just download it. You need to add google-services.json in your app folder. 




Now open android studio. 
->Click on start a new android studio-project. 
->Provide your application-name, company domain and package-name. Here you need to provide package-name() as you given in firebase.
->Click on Finish and launch project.

After launching project, you have downloaded google-services.json file, you need to add this file to your app directory, which you can find when you open your file structure to Project. 



After that you need to add the gms dependency in your project-level build.gradle file.
classpath 'com.google.gms:google-services:3.0.0'

Then, add the corresponding plugin in your app-level build.gradle. You will also need to add a Firebase messaging dependency in this file.

compile 'com.google.firebase:firebase-core:9.2.0'
compile 'com.google.firebase:firebase-messaging:9.2.0'
apply plugin: 'com.google.gms.google-services'

If you are using google-play service in your app, keep same version as you provided for firebase. 
compile 'com.google.android.gms:play-services-location:9.2.0'
compile 'com.google.android.gms:play-services-places:9.2.0'

After adding, sync your project now. Now we will create one more activity SecondActivity.java, when any notification come, on click Notification, it will redirect to SecondActivity. 

SecondActivity.java


public class SecondActivity extends AppCompatActivity {
    @Override    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

}


activity_second.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
android:layout_width="match_parent"   
android:layout_height="match_parent"    
tools:context="com.demo.notification.SecondActivity">
    <TextView        
            android:id="@+id/textView"        
            android:layout_width="wrap_content"        
            android:layout_height="wrap_content"        
            android:text="SecondActivity"        
            app:layout_constraintLeft_toLeftOf="parent"        
            app:layout_constraintRight_toRightOf="parent"        
            tools:layout_editor_absoluteY="233dp"        
            app:layout_constraintHorizontal_bias="0.501" />

</android.support.constraint.ConstraintLayout >
MainActivity.java
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.demo.notification.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="First Activity!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</android.support.constraint.ConstraintLayout>

In the next step, we will create two service class and also need to add in manifest file. 
Add this bellow code inside manifest file.

<service
            android:name=".MyFirebaseMessagingService"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
        <service android:name=".FirebaseIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
  </service>

also add bellow permission inside manifest.xml


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

Now create the service classes:

MyFirebaseMessagingService.java


import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Random;

public class MyFirebaseMessagingService extends FirebaseMessagingService {


    private static final String TAG = "FCM Service";
    private static final String NOTIFICATION_ID_EXTRA = "notificationId";
    private static final String IMAGE_URL_EXTRA = "imageUrl";
    private static final String ADMIN_CHANNEL_ID ="admin_channel";
    private NotificationManager notificationManager;


    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        //super.onMessageReceived(remoteMessage);

        // TODO: Handle FCM messages here.

        Intent notificationIntent = new Intent(this, SecondActivity.class);
        final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , notificationIntent, PendingIntent.FLAG_ONE_SHOT);
        //You should use an actual ID instead
        int notificationId = new Random().nextInt(60000);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder notificationBuilder =new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(remoteMessage.getData().get("title"))
                .setContentText(remoteMessage.getData().get("message"))
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        notificationManager.notify(notificationId, notificationBuilder.build());
    }

}



Here in above class tells that when any notification arrives, by using onMessageReceived() it will receive the notification and it will show notification on notification bar.

Next create another service class FirebaseIDService, code looks like bellow:

FirebaseIDService.java

import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;


public class FirebaseIDService extends FirebaseInstanceIdService {

    private static final String TAG = "FirebaseIDService";

    @Override
    public void onTokenRefresh() {
        //super.onTokenRefresh();

        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);

        System.out.println("RefreshedToken::::"+refreshedToken);

        // TODO: Implement this method to send any registration to your app's servers.
        //sendRegistrationIDToServer(refreshedToken);
    }

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM InstanceID token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private void sendRegistrationIDToServer(String token) {
        // Add custom implementation, as needed.
    }
}


By using this class, it will generate token-id which will send to server for server-side communication. 
That's it. Our code is ready to execute. Before going to test, one more thing we need do one more thing which is very interesting fact. 
If you don't have any server as of now to test your app, firebase having this facility to check your push notification using post method. If did't have google chrome postman plugin , please install it. 
The base url is : 
https://fcm.googleapis.com/fcm/send 
But to check this, you need server-key. You can find this inside firebase console of your project. After logged in into your account, click on your project, then click on project settings, inside project settings->click on cloud messaging. You will see server key, you need to copy it, it will needed in authorization as key={server-key}.



You need to provide custom body and header for post man. Also you need to add param key 'to', here to value you need to provide tokenID which will be generated in FirebaseIDService.java class.  Providing you all screen shots to help you better understand:








Message write inside your body:
{
  "to":
    "esn_3fn0jw0:APA91bFG8MLMfPFgX6GMordpl6uyr4T2lTxNB0qlMkdRB7RX17diNwnOGa3oCvrzTQ1SyovEEB8w2mjV-Pv80LHP_1ClcN8aq4D3zARum2WG0BN3D9YcQtFPFm0tsnuaJ42zfnwtatnbs0wwxVckPIYHTi3_p-l1EQ",
  "data": {
    "title": "Testing Notification",
    "message": "Hello My Message"
  }

}


Your manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"    
          package="com.demo.notification">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <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=".MyFirebaseMessagingService"            
                android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
        <service android:name=".FirebaseIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>

        <activity android:name=".SecondActivity"></activity>

    </application>

</manifest>

Now Everything is ready, Run your app and click on post, you will get notification. 
Result: 



In above see notification. After clicking on notification, SecondActivity will load as bellow.