Saturday, 26 November 2016

Setting up Firebase Cloud Messaging (FCM) in Android application

Background

In last post we say what FCM was and how is it better then the old GCM notifications. 
 Last post was mainly about your server configuration to send FCM notification to a single device. But that assumed that your device is already registered to FCM server and your server has that ID. In this post we will see how to create, register and setup FCM on your Android device. This can be your smart phone or your smart watch app.


Getting started with Firebase Cloud Messaging (FCM)

First of all you need to log into Firebase console -
Log in. Signup if you already don't own a account. Once done you will need to create a new project.





 Once you do that you should see following page.


 As mentioned in previous post as FCM is cross platform you can see Android/iOS/Web. We will concentrate on Android for now. So go ahead and select it. Post clicking it you have 3 steps to perform

  1. provide your android bundle iD
  2. Download google-service.json file and put it under your app folder of Android project
  3. Add dependency to classpath







In app level build.gradle add the firebase dependency you need. For eg in this case we need cloud messaging for FCM. So you can add

compile 'com.google.firebase:firebase-messaging:10.0.0'


You can see all available dependencies here -

under Available libraries section. It looks like below -




Once that is setup your configuration is more or less done. You now also see the server API id we used in previous post from  this project that you have just created. Anyway lets move on the code changes we need.

Code changes needed

Add following services in your manifest file of android module -
        <service android:name="com.osfg.android.watch.MyFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
        <service android:name="com.osfg.android.watch.MyFirebaseInstanceIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>

These services are basically the ones which generate token (registration id we need while sending FCM from server) and receiving message from server. Code for them goes as follows -



package com.osfg.android.watch;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
/**
 * Created by athakur on 11/25/16.
 */
public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String loggerName = MyFirebaseMessagingService.class.getSimpleName();

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

        Log.d(loggerName,"From: " + remoteMessage.getFrom());

        // Check if message contains a data payload.
        if (remoteMessage.getData() != null) {
            Log.d(loggerName, "Message data payload: " + remoteMessage.getData());

            String title = remoteMessage.getData().get("messageTitle");
            String body = remoteMessage.getData().get("messageBody");

            if(StringUtils.hasText(title) && StringUtils.hasText(body))
            {
                Log.d(loggerName, "Showing notification for message");
                showNotification(title, body,this);
            }

        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d(loggerName, "Message Notification Body: " + remoteMessage.getNotification().getBody());
            showNotification(remoteMessage.getNotification().getBody(),this);
        }
    }
}




MyFirebaseMessagingService class will get the  payload send by server during FCM notification. Your payload can have data or notification payload. Notification payload is directly shown as notification on android device where as data payload needs to be handle by your client application


package com.osfg.android.watch;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
/**
 * Created by athakur on 11/25/16.
 */
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {

    private static final String loggerName = MyFirebaseInstanceIDService.class.getSimpleName();

    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(loggerName, "FCM token refreshed: " + refreshedToken);

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        sendFcmTokenToServer(refreshedToken);
    }

    private void sendFcmTokenToServer(String token) {
        Log.d(loggerName, "Sending FCM refresh token to server");
    }
}



And you should be done.  MyFirebaseInstanceIDService class will give you a callback when token is refreshed , you need to update it on your server. Once that is done your server will be able to send FCM notifications to you (exactly what we saw in last post).


Once you do this on your app start these service should automatically start. You will get token in callback and message in other callback of respective services that we have implemented. You can take actions appropriately. Sync data or show notification etc.


NOTE

I have already implemented this in a demo android app that you can refer to. Link to github project -

Related Links

t> UA-39527780-1 back to top