Push notifications are apparently an essential thing in Android Application. It helps us gaining user retention, increasing active user, etc. To send a push notification to all our app users, we can use Firebase Cloud Messaging. We can send some promotional as well as regular information using Firebase Cloud Messaging (or FCM) very quickly.
So this post is about Firebase Cloud Messaging, and today we will learn how we can use Firebase Cloud Messaging in our android application.
Table of Contents
What is Firebase Cloud Messaging?
It is a service provided by Google. So what Google says is “Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages at no cost.”
So it is free and at the same time easy to use. Previously we were using Google Cloud Messaging, but nowadays GCM is obsolete. So you should use firebase only
Message Types
Before moving ahead in the post let’s first understand the types of message that can be sent using FCM.
- Notification Message:Â This type of message is automatically displayed to end user. In this kind of message, we have a predefined set of key-value pairs. We also have a data payload by using it we can set the custom key-value pairs as well.
- Data message: Default does not display this type of message to the end user. To show it we need to add some coding. This message contains only custom key-value pairs.
Adding Firebase Cloud Messaging to Android Project
Creating a new Android Studio Project
- I have created a blank project using an Empty Activity, and I named it FirebasePushExample.
- So you have to do the same, you can change the project name to whatever you want.
Login into Android Studio using your Google Account
If you have logged in already into your Android Studio with your Google Account, then you can skip this step.Â
- You will see a user image at the top right corner of your Android Studio IDE. Click on this icon.
- Now click on the Sign In button. And then authenticate with your Google Account.
Yes, a Google Account is necessary, and if you are an android developer then it is apparent that you are having a google account right?Â
Adding Firebase Cloud Messaging
After logging in to Android Studio with your Google Account, you can quickly add Firebase Cloud Messaging to your project.
- Click on tools and then select Firebase.
- It will open an Assistant Window on the Right. From here you need to Select Cloud Messaging (As shown in the image).
- Here you need to do two things.
Connect to Firebase
- Click on the first Button, Connect to Firebase.
- It will open a new Window.
- From here you can create a new Firebase Project, or you can also select your existing project on firebase if any. Here we are building a new Firebase Project. Just put the name that you want for your project and click on Connect to Firebase.
- Now wait for a while, and you will see Green Connected Message.
Add FCM to your app
- Now click on the second button. Add FCM to your App. It will again open a new window, and here you need to accept the changes.
- Then it will automatically do everything required for adding FCM to your application.
Ways of Receiving Push Notification
Now first, we need to understand how we receive or send notifications using FCM. So there are two ways.
- Using FCM Token:Â We use this method when we want to send a notification to a specific device. Or some dynamic group of devices. Upon initial startup, the firebase SDK generates a registration token for the application. We use this token to identify the device.
- Using Topic:Â We can create topics and let our users subscribe to those topics. Then we can send the message to the topic. And the message will be sent to all the users of that particular topic. In this method, we don’t need to store any token.
We can select from the above two methods to implement in our application. We can use both ways as well. First, we will learn about the FCM Token then we will see the Topic method as well. So let’s do it.Â
Firebase Cloud Messaging using FCM Access Token
In this method first, we will generate the access token. Now to get the access token, we create a class that extends FirebaseInstanceIdService. It is a service that we also need to define inside our Manifest file. Now let’s see how we can do this in our project.
Generating Access Token
- Create a class named MyFirebaseInstanceIdService in your project, and write the following code.
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 |
package net.simplifiedcoding.firebasepushexample; import android.util.Log; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceIdService; /** * Created by Belal on 12/8/2017. */ //the class extending FirebaseInstanceIdService public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService { //this method will be called //when the token is generated @Override public void onTokenRefresh() { super.onTokenRefresh(); //now we will have the token String token = FirebaseInstanceId.getInstance().getToken(); //for now we are displaying the token in the log //copy it as this method is called only when the new token is generated //and usually new token is only generated when the app is reinstalled or the data is cleared Log.d("MyRefreshedToken", token); } } |
- As this class is a service, we need to define it in AndroidManifest.xml as well.
- So open your AndroidManifest.xml file and just before the closing </application> tag add the following code.
1 2 3 4 5 6 7 8 |
<service android:name=".MyFirebaseInstanceIdService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/> </intent-filter> </service> |
- Now run the application, and you will see the token in your logcat.
- Now copy this token and save it anywhere on your system. We will use this token to receive notification.
Common Issues
Keep these things in mind if you are not getting the token.Â
- The token is not everytime generated. We get the token only when firebase refreshes the token. So it might happen that once you run the application and by mistake cleared the log. Then if you again run your application, you will not find the token. So, in this case, you have to uninstall the app, and then you need to again run it.Â
- Google Play Service version should be higher than the Firebase version that you are using in your project. It is always better to update the Google Play Services to the latest version.Â
- You are seeing the log of a different emulator or device. Confirm that emulator selected in the top of the logcat is the same where you are running the application.Â
Receiving Messages
To receive the message we need to create a class that will extend FirebaseMessagingService. Here we will override a method onMessageReceived() that is called when we receive a message. Again this is also a service, so we need to define it in our AndoirdManifest.xml
- Create a class named MyFirebaseMessagingService and write the following code.
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 |
package net.simplifiedcoding.firebasepushexample; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; /** * Created by Belal on 12/8/2017. */ //class extending FirebaseMessagingService public class MyFirebaseMessagingService extends FirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); //if the message contains data payload //It is a map of custom keyvalues //we can read it easily if(remoteMessage.getData().size() > 0){ //handle the data message here } //getting the title and the body String title = remoteMessage.getNotification().getTitle(); String body = remoteMessage.getNotification().getBody(); //then here we can use the title and body to build a notification } } |
- Now again define it using the below XML code in your AndroidManifest.xml just before the closing tag </application>.
1 2 3 4 5 6 7 8 |
<service android:name=".MyFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service> |
- But to see the notification we need to build it. So now let’s make the notification.
Building Push Notification
Now let’s build the Push Notification. For this, I will use a Singleton class.
Note: From Android Oreo, you need to create a notification channel or else notification will not be displayed.Â
- So first we will define some constants for our Notification Channel in a separate class. Create a class named Constants. And write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package net.simplifiedcoding.firebasepushexample; /** * Created by Belal on 12/8/2017. */ public class Constants { public static final String CHANNEL_ID = "my_channel_01"; public static final String CHANNEL_NAME = "Simplified Coding Notification"; public static final String CHANNEL_DESCRIPTION = "www.simplifiedcoding.net"; } |
- Now, create a class named MyNotificationManager and write the following code.
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 67 68 69 70 71 72 73 74 75 76 77 78 79 |
package net.simplifiedcoding.firebasepushexample; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.support.v4.app.NotificationCompat; import static android.content.Context.NOTIFICATION_SERVICE; /** * Created by Belal on 12/8/2017. */ public class MyNotificationManager { private Context mCtx; private static MyNotificationManager mInstance; private MyNotificationManager(Context context) { mCtx = context; } public static synchronized MyNotificationManager getInstance(Context context) { if (mInstance == null) { mInstance = new MyNotificationManager(context); } return mInstance; } public void displayNotification(String title, String body) { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mCtx, Constants.CHANNEL_ID) .setSmallIcon(R.drawable.app_icon) .setContentTitle(title) .setContentText(body); /* * Clicking on the notification will take us to this intent * Right now we are using the MainActivity as this is the only activity we have in our application * But for your project you can customize it as you want * */ Intent resultIntent = new Intent(mCtx, MainActivity.class); /* * Now we will create a pending intent * The method getActivity is taking 4 parameters * All paramters are describing themselves * 0 is the request code (the second parameter) * We can detect this code in the activity that will open by this we can get * Which notification opened the activity * */ PendingIntent pendingIntent = PendingIntent.getActivity(mCtx, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT); /* * Setting the pending intent to notification builder * */ mBuilder.setContentIntent(pendingIntent); NotificationManager mNotifyMgr = (NotificationManager) mCtx.getSystemService(NOTIFICATION_SERVICE); /* * The first parameter is the notification id * better don't give a literal here (right now we are giving a int literal) * because using this id we can modify it later * */ if (mNotifyMgr != null) { mNotifyMgr.notify(1, mBuilder.build()); } } } |
Testing a Local Notification
Before moving ahead, we will confirm that the notification is working correctly. For this, we will create a local notification from the app itself.
- Come on MainActivity.java and write the following code.
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 |
package net.simplifiedcoding.firebasepushexample; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import com.google.firebase.iid.FirebaseInstanceId; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * If the device is having android oreo we will create a notification channel * */ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); int importance = NotificationManager.IMPORTANCE_HIGH; NotificationChannel mChannel = new NotificationChannel(Constants.CHANNEL_ID, Constants.CHANNEL_NAME, importance); mChannel.setDescription(Constants.CHANNEL_DESCRIPTION); mChannel.enableLights(true); mChannel.setLightColor(Color.RED); mChannel.enableVibration(true); mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400}); mNotificationManager.createNotificationChannel(mChannel); } /* * Displaying a notification locally */ MyNotificationManager.getInstance(this).displayNotification("Greetings", "Hello how are you?"); } } |
- Now try running your application.
- If you see this then awesome, it is working.
Testing Notification from Firebase Console
- Now let’s send a real notification from Firebase Console.
- Open firebase console, then open your project that you are using. Then from the left menu click on grow -> notifications.Â
- And after pressing the Send Message button, you should see your message on the application.
- As you can see it is working fine, as we see the notification.
Firebase Cloud Messaging using Topic Subscription
Now let’s see how we can send to notifications to the devices that are subscribed to a particular group. Obviously, for this, we need to create a group first. So here is the method.
- Call FirebaseMessaging.getInstance().subscribeToTopic(“put_your_topic_here”);
- The above method will subscribe the user to the topic, if the topic is not an existing topic firebase will create the topic specified.
- Now here in your application, we will give some topics to the user to subscribe. For this let’s create the interface.
Creating Interface
- Go to your strings.xml file and define the following array. These are the topics that a user can subscribe.
1 2 3 4 5 6 7 8 9 10 11 |
<resources> <string name="app_name">FirebasePushExample</string> <array name="topics"> <item>notifications</item> <item>promotional_messages</item> </array> </resources> |
- Now copy the following for activity_main.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 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="net.simplifiedcoding.firebasepushexample.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" android:padding="20dp"> <Spinner android:id="@+id/spinnerTopics" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="15dp" android:entries="@array/topics" /> <Button android:id="@+id/buttonSubscribe" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Subscribe" /> </LinearLayout> </RelativeLayout> |
- The above code will generate the following UI.
- From here user will select the topic and then click on the button to subscribe.
Subscribing to a Topic
- Now modify your MainActivity.java as below. The code is straightforward and self-explaining.
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 |
package net.simplifiedcoding.firebasepushexample; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Spinner; import android.widget.Toast; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.messaging.FirebaseMessaging; public class MainActivity extends AppCompatActivity { Spinner spinner; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); spinner = findViewById(R.id.spinnerTopics); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); int importance = NotificationManager.IMPORTANCE_HIGH; NotificationChannel mChannel = new NotificationChannel(Constants.CHANNEL_ID, Constants.CHANNEL_NAME, importance); mChannel.setDescription(Constants.CHANNEL_DESCRIPTION); mChannel.enableLights(true); mChannel.setLightColor(Color.RED); mChannel.enableVibration(true); mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400}); mNotificationManager.createNotificationChannel(mChannel); } findViewById(R.id.buttonSubscribe).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String topic = spinner.getSelectedItem().toString(); FirebaseMessaging.getInstance().subscribeToTopic(topic); Toast.makeText(getApplicationContext(), "Topic Subscribed", Toast.LENGTH_LONG).show(); } }); } } |
- Now again, try running your application.
- Yes, it is working fine. Now let’s try sending a notification to this topic.
Sending Notification to Topic from Firebase Console
- Again go to the firebase console and go to the notification.
- Now this time we will select send to the topic instead of a single device.
- After clicking on send, you should see the notification on your device.
- Bingo! It is working fine.
Unsubscribing from a Topic
Sometimes user also wants that “I don’t want to receive notification”. In this case, you have to give an option to unsubscribe as well.
- To unsubscribe from a topic, you need to call FirebaseMessaging.getInstance().unsubscribeFromTopic(“your_topic”);
Firebase Cloud Messaging Tutorial Source Code
If you still have some problem following the post (it was very long, you have to follow it carefully) then here I have my source code in my GitHub repository. You just need to unlock the link by using a social button given below.
[sociallocker id=1372] Firebase Cloud Messaging Tutorial Source Code [/sociallocker]
So that’s all for this Firebase Cloud Messaging Tutorial friends. In the next post, we will learn to build our admin panel to send and manage notifications. If you found this firebase cloud messaging (FCM) tutorial helpful then please SHARE it with your friends. Thank You 🙂