Android

Learn how to send push notifications for messages.

👍

Sample App

Sample app demonstrating Push Notification using CometChat Pro Extension

The Push Notification extension allows you to send push notifications to mobile apps and desktop browsers.

There are a few steps to activate this extension:

Setup Firebase

Step 1: Add Firebase to your Android app

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

Create new project in the Firebase ConsoleCreate new project in the Firebase Console

Create new project in the Firebase Console

After creating a Firebase project, click on the Android logo to add Firebase to your Android app.

Add Firebase to your Android appAdd Firebase to your Android app

Add Firebase to your Android app

And then follow the on-screen instructions.

Add `google-services.json`Add `google-services.json`

Add google-services.json

Step 2: Note the Firebase Server key

Click on the Settings icon (cog wheel) and select Project Settings. Under Cloud Messaging, you will find Server key. Make a note of it (will be required when configuring the Push Notification extension in the CometChat dashboard).

Note the Server keyNote the Server key

Note the Server key

Step 3: Add FCM key to CometChat Dashboard.

  1. Login to the CometChat Dashboard.
  2. On the Extensions page add the Push Notifications extension.
  3. Go to the Installed tab and open the Settings for this extension.
  4. Enter the Title (usually name of the app) and FCM Server key.
  5. You can also toggle the triggers for sending Push Notifications. The triggers can be classified into 3 main categories:
    a. Message Notifications
    b. Call Notifications
    c. Group Notifications

Step 4: Set up a Firebase Cloud Messaging client app on Android

To enable Firebase products in your app, add the google-services plugin to your Gradle files.

In your root-level (project-level) Gradle file (build.gradle), Check that you have Google's Maven repository.

buildscript {

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
  }

  dependencies {
    // ...

    // Add the following line:
    classpath 'com.google.gms:google-services:4.3.3'  // Google Services plugin
  }
}

allprojects {
  // ...

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
    // ...
  }
}

In your module (app-level) Gradle file (usually app/build.gradle), apply the Google Services Gradle plugin and add the dependencies for the Firebase Cloud Messaging.

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

android {
    //...
}

dependencies {
   //..
    implementation 'com.google.firebase:firebase-messaging:20.2.4'
    //..
    implementation 'com.cometchat:pro-android-chat-sdk:2.1.0'
}

For more details please check below link:

Step 5: Handle Calls and Messages using FirebaseMessagingService & Broadcast Receiver.

FirebaseMessagingService provides a method which helps to register token for client app by overriding onNewToken.

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseService";
    public static String token;

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

Subscribe to topics

To receive push notifications, the logged-in user must subscribe to two types of topics:

  1. Their own topic - All the messages for one-on-one conversations that are sent to the logged-in user are received using this topic. The topic you must subscribe to is AppID_user_UID where AppID is your CometChat App ID and UID is the logged-in user's ID.

  2. Topics for all the groups the logged in user is a part of - All the messages for a group conversation are received using these topics. For every group joined, the logged-in user will have to subscribe to the topic for that group. For every group, you must subscribe to AppID_group_GUID where AppID is your CometChat App ID and GUID is the group's ID.

📘

Note

In case of user, you need to subscribe to logged-in user after the user gets Logged In.
And you can unsubscribe the user when you logout as a user.

In the case of group, you need to subscribe to a group whenever user joins or added to a group. And you can unsubscribe a group whenever user leaves or kicked out of the group.

public static void subscribeUserNotification(String UID) {
        FirebaseMessaging.getInstance().subscribeToTopic(AppConfig.AppDetails.APP_ID + "_"+ CometChatConstants.RECEIVER_TYPE_USER +"_" +
                UID);
    }

    public static void unsubscribeUserNotification(String UID) {
        FirebaseMessaging.getInstance().unsubscribeFromTopic(AppConfig.AppDetails.APP_ID + "_"+ CometChatConstants.RECEIVER_TYPE_USER +"_" +
                UID);
    }

    public static void subscribeGroupNotification(String GUID) {
        FirebaseMessaging.getInstance().subscribeToTopic(AppConfig.AppDetails.APP_ID + "_"+ CometChatConstants.RECEIVER_TYPE_GROUP +"_" +
                GUID);
    }

    public static void unsubscribeGroupNotification(String GUID) {
        FirebaseMessaging.getInstance().unsubscribeFromTopic(AppConfig.AppDetails.APP_ID + "_"+ CometChatConstants.RECEIVER_TYPE_GROUP +"_" +
                GUID);
    }

🚧

Please note:

UID in case of users and GUID in case of groups are converted to lowercase by the Chat API. These are then used for generating the topic.

To receive messages, you need to override the onMessageReceived(RemoteMessage remoteMessage).

You can check the whole code of MyFirebaseMessagingService.java which 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;

    public static void subscribeUserNotification(String UID) {
        FirebaseMessaging.getInstance().subscribeToTopic(AppConfig.AppDetails.APP_ID + "_"+ CometChatConstants.RECEIVER_TYPE_USER +"_" +
                UID).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.e(TAG, UID+ " Subscribed Success");
            }
        });
    }

    public static void unsubscribeUserNotification(String UID) {
        FirebaseMessaging.getInstance().unsubscribeFromTopic(AppConfig.AppDetails.APP_ID + "_"+ CometChatConstants.RECEIVER_TYPE_USER +"_" +
                UID).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.e(TAG, UID+ " Unsubscribed Success");
            }
        });
    }

    public static void subscribeGroupNotification(String GUID) {
        FirebaseMessaging.getInstance().subscribeToTopic(AppConfig.AppDetails.APP_ID + "_"+ CometChatConstants.RECEIVER_TYPE_GROUP +"_" +
                GUID).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.e(TAG, GUID+ " Subscribed Success");
            }
        });
    }

    public static void unsubscribeGroupNotification(String GUID) {
        FirebaseMessaging.getInstance().unsubscribeFromTopic(AppConfig.AppDetails.APP_ID + "_"+ CometChatConstants.RECEIVER_TYPE_GROUP +"_" +
                GUID);
    }

    @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, "Answers", PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, getCallIntent("Answers"), 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;
    }
}

CallNotificationAction.class is a BroadcastReceiver which is used to handle call events when app is in background state. Since Android O, there have been certain restrictions added for background tasks and users cannot launch intent directly from the service.
For more info please check below link.
https://developer.android.com/guide/components/activities/background-starts

Below you can check 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) {

                }
            });
        }
    }
}
  • You can replace CometChatCallActivity.java with the Activity in which you have created to handle calls.*

You also need to add both of the above mentioned file in your AndroidManifest.xml to make Push notification work in 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" />

Step-6 Notification Channel

From Android O and above you need to use NotificationChannel to show notifications.
You can add the below method in your Application class and call it in OnCreate(). This method will manage the notification channel for your app.

private void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.app_name);
            String description = getString(R.string.channel_description);
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel channel = new NotificationChannel("2", name, importance);
            channel.setDescription(description);
            channel.enableVibration(true);
            channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }

    }

Handle Custom Messages

  • To receive notification of CustomMessage, you need to set metadata while sending the CustomMessage.
String receiverId="superhero1";
JSONObject metaData=new JSONObject();
JSONObject customData=new JSONObject();

try {
   metaData.put("pushNotification","Your Notification Message");
   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","Your Notification Message")
       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"));

Messages-

Input

Notification Alert

Simple text message

SenderName: text message

Attachment(s) with text

SenderName: text message

An attachment without text

SenderName: has sent you a/an Type

Attachments without text

SenderName: has sent you Types

📘

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"
   }
}

Did this page help you?