/ SDKs / Android
SDKs
Chat SDKs Android v4
Chat SDKs Android
Chat SDKs
Android
Version 4

Set up push notifications for HMS

Copy link

This part covers the following step-by-step instructions of our push notifications for HMS.

Note: See Set up push notifications for FCM if you want to learn how to set up notifications for FCM.


Step 1: Generate app ID and app secret for HMS

Copy link

The Sendbird server requires your app ID and app secret to send notification requests to HMS on behalf of your server. This is required for HMS to authorize HTTP requests.

If you already have your app ID and app secret, you can skip this step and go directly to Step 2: Register app ID and app secret to Sendbird Dashboard.

  1. Go to the AppGallery Connect. If you don't have a project for your client app, create a new project.

  1. Select your project card to move to Project Settings.

  2. Go to Convention > App Information and copy your App ID and App secret to use them on Sendbird Dashboard later.

  1. During the registration process, enter your package name, download the agconnect-services.json file, and place it in your Android app module root directory.


Step 2: Register app ID and app secret to Sendbird Dashboard

Copy link

Register your app ID and app secret to Sendbird Dashboard as follows.

  1. Sign in to your dashboard and go to Settings > Chat > Push notifications.

  2. Turn on Push notifications and select Send to devices when all offline.

  3. Click Add credentials and register the app ID and app secret acquired at Step 1.


Step 3: Set up Huawei Message Service and the HMS SDK

Copy link

Add the following dependency for the Cloud Messaging Android library to your build.gradle files that are at the project level and app level.

Project levelApp level
allprojects {
    repositories {
        // ...
        maven { url 'https://developer.huawei.com/repo/' }
    }
}
buildscript {
    repositories {
        // ...
        maven { url 'http://developer.huawei.com/repo/' }
    }
    dependencies {
        // ...
        classpath 'com.huawei.agconnect:agcp:1.1.1.300'
    }
}

Then the Chat SDK writes and declares our push notifications with multi-device support in the manifest while you build your client app. If you declare another push service that extends FirebaseMessagingService in your client app's manifest, this multi-device support doesn't work in the app.

To learn more about this step, refer to Huawei's Preparations guide. The Push Kit sample code for Android guide is another helpful reference.


Step 4: Implement multi-device support in your Android app

Copy link

The following classes and interface are provided to implement push notifications with multi-device support.

Class or interfaceDescription

SendbirdHmsPushHandler

A class that provides the onNewToken()and onMessageReceived()callbacks as well as other callbacks to handle a user's registration token and receive notification messages from HMS.

SendbirdPushHelper

A class that provides the methods to register and unregister a SendbirdHmsPushHandler handler, check if the same message has already been received, and more.

OnPushTokenReceiveListener

An interface that contains the onReceived() callback to receive a user's registration token from HMS.

These are used to inherit your MyHmsMessagingService class from the SendbirdHmsPushHandler class and implement the following.

class MyHmsMessagingService(override val context: Context) : SendbirdHmsPushHandler() {
    // This is invoked when a notification message has been delivered to the current user's client app.
    override fun onMessageReceived(context: Context, remoteMessage: com.huawei.hms.push.RemoteMessage) {
        try {
            val message = remoteMessage.dataOfMap["message"]
            val payload = remoteMessage.dataOfMap["sendbird"] ?: return
            val sendbirdJson = JSONObject(payload)
            val channelJson = sendbirdJson.getJSONObject("channel")
            val channelUrl = channelJson.getString("channel_url")

            // Also if you intend to generate your own notifications as a result of a received HMS
            // message, here is where that should be initiated. See the sendNotification method below.
            sendNotification(context, message, channelUrl)
        } catch (e: JSONException) {
            e.printStackTrace()
        }
    }

    override fun onNewToken(newToken: String?) {
        pushToken = newToken
    }

    override val isUniquePushToken: Boolean
        get() = false

    // The alwaysReceiveMessage() method determines whether push notifications for new messages
    // are delivered even when the app is in foreground.
    // The default is false, meaning push notifications are delivered
    // only when the app is in the background.
    override fun alwaysReceiveMessage(): Boolean {
        return false
    }

    fun sendNotification(context: Context, messageBody: String?, channelUrl: String) {
        // Customize your notification containing the received HMS message.
    }

    companion object {
        var pushToken: String? = null
        fun getPushToken(callback: ((pushToken: String?, e: SendbirdException?) -> Unit)) {
            if (!pushToken.isNullOrEmpty()) {
                callback(pushToken, null)
                return
            }

            SendbirdPushHelper.getPushToken { token, e ->
                if (token != null) {
                    pushToken = token
                }
                callback(pushToken, e)
            }
        }
    }
}

Note: Upon initial startup of your app, the HMS SDK generates a unique and app-specific registration token for the client app instance on your user's device. HMS uses this registration token to determine which device to send notification messages to.

In order to receive information about push notification events for the current user from the Sendbird server, register a MyHmsMessagingService instance to SendbirdPushHelper as an event handler.

To receive a push notification when the app is in the background or closed, you must register the MyHmsMessagingService instance. This instance isn't dependent on Sendbird Chat SDK, so even in cases where Sendbird.init() isn't called in Application, MyHMSMessagingService must be registered in the Application instance's onCreate() method as shown in the code below.

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        SendbirdChat.init(
            InitParams(APP_ID, applicationContext, true),
            object : InitResultHandler {
                override fun onMigrationStarted() {}
                override fun onInitFailed(e: SendbirdException) {}
                override fun onInitSucceed() {}
            }
        )
        // Not dependent on SendbirdChat.init(). Must be called in Application.
        SendbirdPushHelper.registerHmsPushHandler(MyHmsMessagingService())
    }
}

Also, register a MyHmsMessagingService instance when a user logs into the Sendbird server as follows.

SendbirdChat.connect(USER_ID) { user, e ->
    if (e != null) {
        // Handle error.
    }
    // ...

    SendbirdPushHelper.registerHmsPushHandler(MyHmsMessagingService())
}

The instance should be unregistered when a user logs out from the Sendbird server as follows.

SendbirdPushHelper.unregisterPushHandler(
    IS_UNREGISTER_ALL,
    object : SendbirdPushHelper.OnPushRequestCompleteListener {
        override fun onComplete(isRegistered: Boolean, token: String?) {
            SendbirdChat.disconnect {
                // Clear user-related data.
            }
        }

        override fun onError(e: SendbirdException) {
            // Handle error.
        }
    }
)

Step 5: Handle an HMS message payload

Copy link

The Sendbird server sends push notification payloads as HMS notification messages, which contain notification-related data in the form of key-value pairs. Unlike notification messages, the client app needs to parse and process these data messages in order to display them as local notifications.

The following code shows how to receive a push notification payload and parse it as a local notification. The payload consists of two properties: message and sendbird. The message property is a string generated according to a notification template you set on the Sendbird Dashboard. The sendbird property is a JSON object which contains all the information about the message a user has sent. Within MyFirebaseMessagingService.java, you can show the parsed messages to users as a notification by using your custom sendNotification() method.

Note: See Huawei’s Receive messages in an Android app guide to learn more about how to implement code to receive and parse an HMS notification message, how notification messages are handled depending on the state of the receiving app, how to edit the app manifest, and how to override the onMessageReceived() method.

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    try {
    if (remoteMessage.getDataOfMap().containsKey("sendbird")) {
        val sendbird = JSONObject(remoteMessage.getDataOfMap().get("sendbird"))
        val channel = sendbird.get("channel") as JSONObject
        val channelUrl = channel["channel_url"] as String
        val messageTitle = sendbird.get("push_title") as String
        val messageBody = sendbird.get("message") as String
        // If you want to customize a notification with the received HMS message,
        // write your method like sendNotification() below.
        sendNotification(context, messageTitle, messageBody, channelUrl)
    }
    } catch (e: JSONException) {
    e.printStackTrace()
    }
}
// ...
fun sendNotification(
    context: Context,
    messageTitle: String,
    messageBody: String,
    channelUrl: String
) {
    // Implement your own way to create and show a notification containing the received HMS message.
    val notificationBuilder = NotificationCompat.Builder(context, channelUrl)
    .setSmallIcon(R.drawable.img_notification)
    .setColor(Color.parseColor("#7469C4")) // small icon background color
    .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.logo_sendbird))
    .setContentTitle(messageTitle)
    .setContentText(messageBody)
    .setAutoCancel(true)
    .setSound(defaultSoundUri)
    .setPriority(Notification.PRIORITY_MAX)
    .setDefaults(Notification.DEFAULT_ALL)
    .setContentIntent(pendingIntent)
}

The following is a complete payload format of the sendbird property, which contains a set of provided key-value items. Some fields in the push notification payload can be customized in Settings > Chat > Push notifications on Sendbird Dashboard. For example, push_title and push_alert are created based on the Title and Body text you set in Push notification content templates, respectively, in the Push notifications menu. In order to display them in a local notification, pass push_title and push_alert of the push notification payload into the setContentTitle and setContentText methods of the NotificationCompat.Builder class, respectively. Also, the channel_unread_count field can be added into or removed from the payload in the same menu on the Sendbird Dashboard.

{
    "category": "messaging:offline_notification",
    "type": string,                 // Message type: MESG, FILE, or ADMM
    "message": string,              // User input message
    "custom_type": string,          // Custom message type
    "message_id": long,          // Message ID
    "created_at": long,          // The time that the message was created, in a 13-digit Unix milliseconds format
    "app_id": string,                // Application's unique ID
    "unread_message_count": int,    // Total number of new messages unread by the user
    "channel": {
        "channel_url": string,      // Group channel URL
        "name": string,          // Group channel name
        "custom_type": string,       // Custom Group channel type
        "channel_unread_count": int // Total number of unread new messages from the specific channel
    },
    "channel_type": string,         // A value of channel_type is set by the system. The value of messaging indicates a distinct group channel while group_messaging indicates a private group channel and chat indicates all other cases.
    "sender": {
        "id": string,                // Sender's unique ID
        "name": string,          // Sender's nickname
        "profile_url": string,       // Sender's profile image URL
        "require_auth_for_profile_image": false,
        "metadata": {}
    },
    "recipient": {
        "id": string,                // Recipient's unique ID
        "name": string              // Recipient's nickname
    },
    "files": [],                        // An array of data regarding the file message, such as filename
    "translations": {},          // The items of locale:translation
    "push_title": string,           // Title of a notification message that can be customized in the Sendbird Dashboard with or without variables
    "push_alert": string,           // Body text of a notification message that can be customized in the Sendbird Dashboard with or without variables
    "push_sound": string,           // The location of a sound file for notifications
    "audience_type": string,            // The type of audiences for notifications
    "mentioned_users": {
        "user_id": string,          // The ID of a mentioned user
        "nickname": string,         // The nickname of a mentioned user
        "profile_url": string,      // Mentioned user's profile image URL
        "require_auth_for_profile_image": false
}

Step 6: Enable multi-device support on Sendbird Dashboard

Copy link

After the above implementation has been completed, multi-device support should be enabled on Sendbird Dashboard by going to Settings > Application > Notifications > Push notifications for multi-device users.