Android

Learn how to setup CometChat Pro Enhanced Push Notifications in Android

The Push Notification extension allows you to send push notifications to mobile apps and desktop browsers.
In this section, we will see how to send Push Notifications to your Android app using Firebase Cloud Messaging or FCM.

I want to checkout the Sample app.

Click on the link below to check out our Android Push Notifications Sample app.

Follow the steps mentioned in the README.md file.

View Sample App on GitHub

Firebase Project Setup

Visit Firebase Console and login/signup using your GMail ID.

Step 1: Create a new Firebase Project

Head over to the Firebase Console to create a new project.

This is a simple 3 step process where:

  1. You give a name to your project
  2. Add Google Analytics to your project (Optional)
  3. Configure Google Analytics account (Optional)

Click on Create and you are ready to go.

Step 2: Add Firebase to your Android App

  1. Click on the Android icon as shown on the screen below.
  1. Register your Android app by providing the following details:
    a. Android Package name
    b. App nickname (optional)
    c. Debug signing certificate SHA-1 (optional)
  1. Download the google-services.json file and place it in the required location in your project.
  1. Add Firebase SDK by copying and pasting the snippets in the Project-level build.gradle file.
  1. Add Firebase SDK by copying and pasting the snippets in the App-level build.gradle file.
  1. Click on 'Continue to Console' to finish the setup.

Step 3: Get the Server Key

  1. Once you are back to Console, you will see the Android app added to the Firebase Project.
  2. Click on the app and open up the Settings page.
  3. Go to the "Cloud Messaging" section and get the Server Key. This will be required in the next step.

Extension Setup

Step 1: Enable the extension

  1. Login to the CometChat Dashboard.
  2. Select an existing app or create a new one.
  3. Go to the "Extensions" section and Enable the Push Notifications extension.
  4. Go to the "Installed" tab in the same section and open the settings for this extension.

Step 2: Save your Settings

On the Settings page you need to enter the following:

  1. Push Notifications Title
  • This is usually the name of your app.
  1. FCM Server key
  • Paste the Server key obtained in Step 3 of The Firebase Project Setup.
  1. Set extension version
  • If you are setting it for the first time, Select V2 to start using the enhanced version of the Push Notification extension. The enhanced version uses Token-based approach for sending Push Notifications and is simple to implement.
  • If you already have an app using V1 and want to migrate your app to use V2, then Select V1 & V2 option. This ensures that the users viewing the older version of your app also receive Push Notifications.
  • Eventually, when all your users are on the latest version of your app, you can change this option to V2, thus turning off V1 (Topic-based) Push Notifications completely.
  1. Notification Triggers
  • Select the triggers for sending Push Notifications. These triggers can be classified into 3 main categories:
    -- Message Notifications
    -- Call Notifications
    -- Group Notifications
  • These are pretty self-explanatory and you can toggle them as per your requirement.

Android App Setup

In the Firebase Project setup, we did the following things:

  1. Added google-services.json file to the project.
  2. Added the required Firebase SDK snippets to the Project-level build.grade file.
  3. Added the required Firebase SDK snippets to the App-level build.gradle file.

If you want more details, check the below Firebase Documentation:

Step 1: Register the FCM Token on user login

  1. Initialize CometChat and then login your user.
  2. On successful login, you can register the obtained FCM Token using CometChat.registerTokenForPushNotification() function call. (You can see the process of getting the FCM Token in the next step)
CometChat.registerTokenForPushNotification(MyFirebaseMessagingService.token, new CometChat.CallbackListener<String>() {
    @Override
    public void onSuccess(String s) {
        Log.e( "onSuccessPN: ",s );
    }
    @Override
    public void onError(CometChatException e) {
        Log.e("onErrorPN: ",e.getMessage() );
    }
});
CometChat.registerTokenForPushNotification(MyFirebaseMessagingService.token, object : CallbackListener<String?>() {
            override fun onSuccess(s: String?) {
                Log.e("onSuccessPN: ", s)
            }

            override fun onError(e: CometChatException) {
                Log.e("onErrorPN: ", e.message)
            }
        })

To fetch the registered token you can use below Firebase method.

FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(
  new OnCompleteListener<InstanceIdResult>() {
    @Override
    public void onComplete(@NonNull Task<InstanceIdResult> task) {
        if (!task.isSuccessful()) {
          return;
        }
      token = task.getResult().getToken();
      //CometChat.registerTokenForPushNotification(token, CometChat.CallbackListener<String>());
    }
});
FirebaseInstanceId.getInstance().getInstanceId()
   .addOnCompleteListener(object : OnCompleteListener<InstanceIdResult?>() {
     fun onComplete(task: com.google.android.gms.tasks.Task<InstanceIdResult>) {
       if (!task.isSuccessful()) {
         return
       }
       token = task.getResult().getToken()
       //CometChat.registerTokenForPushNotification(token,CometChat.CallbackListener<String?>())
     }
   })

Step 2: Receive notifications

  1. The FCM Token can be received by overriding the onNewToken() method. This token is stored as a String variable. You can choose to store it in SharedPreferences as well.
  2. To receive messages, you need to override the onMessageReceived(RemoteMessage remoteMessage).
  3. MyFirebaseMessagingService.java has the code that provides a way you can handle messages received from CometChat users and groups.
package com.cometchat.pro.android.pushnotification.utils;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.util.Log;

import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

import com.cometchat.pro.android.pushnotification.R;
import com.cometchat.pro.android.pushnotification.constants.AppConfig;
import com.cometchat.pro.constants.CometChatConstants;
import com.cometchat.pro.core.Call;
import com.cometchat.pro.helpers.CometChatHelper;
import com.cometchat.pro.models.BaseMessage;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

import constant.StringContract;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseService";
    private JSONObject json;
    private Intent intent;
    private int count=0;
    private Call call;
    public static String token;
    private static final int REQUEST_CODE = 12;

    private boolean isCall;

    @Override
    public void onNewToken(String s) {
        token  = s;
        Log.d(TAG, "onNewToken: "+s);
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        try {
            count++;
            json = new JSONObject(remoteMessage.getData());
            Log.d(TAG, "JSONObject: "+json.toString());
            JSONObject messageData = new JSONObject(json.getString("message"));
            BaseMessage baseMessage = CometChatHelper.processMessage(new JSONObject(remoteMessage.getData().get("message")));
            if (baseMessage instanceof Call){
                call = (Call)baseMessage;
                isCall=true;
            }
            showNotifcation(baseMessage);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public Bitmap getBitmapFromURL(String strURL) {
        if (strURL!=null) {
            try {
                URL url = new URL(strURL);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                Bitmap myBitmap = BitmapFactory.decodeStream(input);
                return myBitmap;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        } else {
            return null;
        }
    }

    private void showNotifcation(BaseMessage baseMessage) {

        try {
            int m = (int) ((new Date().getTime()));
            String GROUP_ID = "group_id";

            NotificationCompat.Builder builder = new NotificationCompat.Builder(this,"2")
                    .setSmallIcon(R.drawable.cc)
                    .setContentTitle(json.getString("title"))
                    .setContentText(json.getString("alert"))
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setColor(getResources().getColor(R.color.colorPrimary))
                    .setLargeIcon(getBitmapFromURL(baseMessage.getSender().getAvatar()))
                    .setGroup(GROUP_ID)
                    .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                    .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));

            NotificationCompat.Builder summaryBuilder = new NotificationCompat.Builder(this,"2")
                    .setContentTitle("CometChat")
                    .setContentText(count+" messages")
                    .setSmallIcon(R.drawable.cc)
                    .setGroup(GROUP_ID)
                    .setGroupSummary(true);
            NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

            if (isCall){
                builder.setGroup(GROUP_ID+"Call");
                if (json.getString("alert").equals("Incoming audio call") || json.getString("alert").equals("Incoming video call")) {
                    builder.setOngoing(true);
                    builder.setPriority(NotificationCompat.PRIORITY_HIGH);
                    builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE));
                    builder.addAction(0, "Answer", PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, getCallIntent("Answer"), PendingIntent.FLAG_UPDATE_CURRENT));
                    builder.addAction(0, "Decline", PendingIntent.getBroadcast(getApplicationContext(), 1, getCallIntent("Decline"), PendingIntent.FLAG_UPDATE_CURRENT));
                }
                notificationManager.notify(05,builder.build());
            }
            else {
                notificationManager.notify(baseMessage.getId(), builder.build());
                notificationManager.notify(0, summaryBuilder.build());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private Intent getCallIntent(String title){
        Intent callIntent = new Intent(getApplicationContext(), CallNotificationAction.class);
        callIntent.putExtra(StringContract.IntentStrings.SESSION_ID,call.getSessionId());
        callIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        callIntent.setAction(title);
        return callIntent;
    }
}
  1. CallNotificationAction.class is a BroadcastReceiver which is used to handle call events when your app is in the background state.
  2. Since Android O, there have been certain restrictions added for background tasks and users cannot launch intent directly from the service. More details here.

Below you can check the full code of CallNotificationAction.java

package com.cometchat.pro.android.pushnotification.utils;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

import androidx.core.app.NotificationManagerCompat;

import com.cometchat.pro.constants.CometChatConstants;
import com.cometchat.pro.core.Call;
import com.cometchat.pro.core.CometChat;
import com.cometchat.pro.exceptions.CometChatException;
import com.cometchat.pro.models.Group;
import com.cometchat.pro.models.User;

import constant.StringContract;
import screen.CallActivity;

public class CallNotificationAction extends BroadcastReceiver {

    String TAG = "CallNotificationAction";
    @Override
    public void onReceive(Context context, Intent intent) {
        String sessionID = intent.getStringExtra(StringContract.IntentStrings.SESSION_ID);
        Log.e(TAG, "onReceive: " + intent.getStringExtra(StringContract.IntentStrings.SESSION_ID));
        if (intent.getAction().equals("Answers")) {
            CometChat.acceptCall(sessionID, new CometChat.CallbackListener<Call>() {
                @Override
                public void onSuccess(Call call) {
                    Intent acceptIntent = new Intent(context, CometChatCallActivity.class);
                    acceptIntent.putExtra(StringContract.IntentStrings.SESSION_ID,call.getSessionId());
                    acceptIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(acceptIntent);
                }

                @Override
                public void onError(CometChatException e) {
                    Toast.makeText(context,"Error "+e.getMessage(),Toast.LENGTH_LONG).show();
                }
            });
            NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
            notificationManager.cancel(05);
        }
        else {
            CometChat.rejectCall(sessionID, CometChatConstants.CALL_STATUS_REJECTED, new CometChat.CallbackListener<Call>() {
                @Override
                public void onSuccess(Call call) {
                    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
                    notificationManager.cancel(05);
                }

                @Override
                public void onError(CometChatException e) {

                }
            });
        }
    }
}
  1. You also need to add both of the above-mentioned files in your AndroidManifest.xml to make Push notification work in the background as well.
<service
    android:name=".MyFirebaseMessagingService" 
    android:exported="true" 
    android:enabled="true">
    <intent-filter>
         <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter> 
</service>
<receiver android:name=".CallNotificationAction" />

Advanced

Sending Custom Notification body

Push notification has 2 parts, namely, the notification title and notification body.
The title can be:
a. Name of the sender in case of one-on-one message. (E.g.: Spiderman)
b. Name of the sender followed by group name for group messages (E.g.: Spiderman @ ComicHeros)

The body of the message depends upon the type of message being sent. You can send a custom body by specifying the pushNotification key followed by some user-defined string for the notification body inside metadata while sending the message.

The following code shows an example of a Custom body using a message of category=custom. This is however not just limited to a custom category of messages.

String receiverId="superhero1";
JSONObject metaData=new JSONObject();
JSONObject customData=new JSONObject();

try {
   metaData.put("pushNotification","Custom Notification body");
   customData.put("yourkey","Your Value");
  } catch (JSONException e) {
   e.printStackTrace();
}

CustomMessage customMessage=new CustomMessage(receiverId,CometChatConstants.RECEIVER_TYPE_USER,customData);
customMessage.setMetadata(metaData);

CometChat.sendCustomMessage(customMessage, new CometChat.CallbackListener<CustomMessage>() {
            @Override
            public void onSuccess(CustomMessage customMessage) {
                Log.d(TAG, "onSuccess: "+customMessage.toString());
            }

            @Override
            public void onError(CometChatException e) {
                Log.d(TAG, "onError: "+e.getMessage());
            }
        });
var receiverId:String="superhero1"
var metaData:JSONObject=JSONObject()
var customData:JSONObject= JSONObject()

  try {
       metaData.put("pushNotification","Custom Notification Body")
       customData.put("yourkey","Your Value")
    } catch (e:JSONException) {
       e.printStackTrace()
   }
var customMessage = CustomMessage(receiverId,CometChatConstants.RECEIVER_TYPE_USER,customData)
customMessage.metadata = metaData;

CometChat.sendCustomMessage(customMessage, object :CometChat.CallbackListener<CustomMessage>() {
       override fun onSuccess(p0: CustomMessage?) {
          Log.d(TAG,"onSuccess ${p0?.toString()}")
        }

       override fun onError(p0: CometChatException?) {
          Log.d(TAG,"onError ${p0?.message}")
       }
})

Converting Push Notification Payloads to Message Objects

CometChat provides a method CometChatHelper.processMessage() to convert the message JSON to the corresponding object of TextMessage, MediaMessage, CustomMessage, Action or Call.

This code needs to be added to the onMessageReceived() method of the FirebaseMessagingService class.

CometChatHelper.processMessage(new JSONObject(remoteMessage.getData().get("message"));

📘

Type of Attachment can be of the following the type
1.CometChatConstants.MESSAGE_TYPE_IMAGE
2.CometChatConstants.MESSAGE_TYPE_VIDEO
3.CometChatConstants.MESSAGE_TYPE_AUDIO
4.CometChatConstants.MESSAGE_TYPE_FILE

Push Notification Payload sample for text and media messages-

{  
   "alert":"Spiderman: Text Message",
   "sound":"default",
   "title":"CometChat Pro",
   "message":{  
      "receiver":"superhero4",
      "data":{  
         "entities":{  
            "receiver":{  
               "entityType":"user",
               "entity":{  
                  "uid":"superhero4",
                  "role":"default",
                  "name":"Wolverine", 
                  "avatar":"http://data.cometchat.com/assets/images/avatars/wolverine.png",
                  "status":"offline"
               }
            },
            "sender":{  
               "entityType":"user",
               "entity":{  
                  "uid":"superhero3",
                  "role":"default",
                  "name":"Spiderman",
                  "avatar":"https://data.cometchat.com/assets/images/avatars/spiderman.png",
                  "status":"offline"
               }
            }
         },
         "text":"Text Message"
      },
      "sender":"superhero3",
      "receiverType":"user",
      "id":"142",
      "sentAt":1555668711,
      "category":"message",
      "type":"text"
   }
}
{
   "alert":"Spiderman: has sent an image",
   "sound":"default",
   "title":"CometChat Pro",
   "message":{
      "receiver":"superhero4",
      "data":{
         "attachments":[
            {
               "extension":"png",
               "size":14327,
               "name":"extension_leftpanel.png",
               "mimeType":"image/png",
               "url":"https://s3-eu-west-1.amazonaws.com/data.cometchat.com/1255466c41bd7f/media/1555671238_956450103_extension_leftpanel.png"
            }
         ],
         "entities":{
            "receiver":{
               "entityType":"user",
               "entity":{
                  "uid":"superhero4",
                  "role":"default",
                  "name":"Wolverine",
                  "avatar":"https://data.cometchat.com/assets/images/avatars/wolverine.png",
                  "status":"offline"
               }
            },
            "sender":{
               "entityType":"user",
               "entity":{
                  "uid":"superhero3",
                  "role":"default",
                  "name":"Spiderman",
                  "avatar":"https://data.cometchat.com/assets/images/avatars/spiderman.png",
                  "status":"offline"
               }
            }
         },
         "url":"https://s3-eu-west-1.amazonaws.com/data.cometchat.com/1255466c41bd7f/media/1555671238_956450103_extension_leftpanel.png"
      },
      "sender":"superhero3",
      "receiverType":"user",
      "id":"145",
      "sentAt":1555671238,
      "category":"message",
      "type":"image"
   }
}

Mute functionality

Check out our documentation on how to add Mute functionality to your apps.


Did this page help you?