Skip to main content

Android UI Kit Sample App (Kotlin)

Reference implementation of Kotlin UI Kit, FCM and Push Notification Setup.

What this guide covers

  • FCM setup and CometChat provider wiring (credentials + Gradle + manifest).
  • Token registration/unregistration so CometChat routes pushes correctly.
  • Handling message pushes with grouped notifications and inline reply.
  • Handling call pushes with ConnectionService for native telecom UI.
  • Deep links/navigation from notifications and payload customization.
  • App icon badge count and grouped notifications using unreadMessageCount from the CometChat push payload.

How FCM and CometChat fit together

  • Why FCM? Google issues device tokens and delivers raw push payloads to Android. You must add google-services.json, the Messaging SDK, and a service receiver (FCMService) so the device can receive pushes.
  • Why a CometChat provider? The Provider ID tells CometChat which FCM credentials to use when sending to your app. Without registering tokens against this ID, CometChat cannot target your device.
  • Token registration bridge: The app retrieves the FCM token and calls CometChatNotifications.registerPushToken(pushToken, PushPlatforms.FCM_ANDROID, providerId, …). That binds the token to your logged-in user so CometChat can route message/call pushes to FCM on your behalf.
  • Payload handling: When FCM delivers a push, your FCMService/FCMMessageBroadcastReceiver parses CometChat’s payload, shows notifications (grouped, inline reply), and forwards intents to your activities. For calls, CometChatVoIPConnectionService surfaces a telecom-grade UI and uses the same payload to accept/reject server-side.
  • Dashboard ↔ app contract: The Provider ID in AppConstants.FCMConstants.PROVIDER_ID must match the dashboard provider you created. The package name in Firebase and the applicationId in Gradle must match, or FCM will reject the token.

1. Prepare Firebase and CometChat

  1. Firebase Console: Add your Android package, download google-services.json into the app module, and enable Cloud Messaging.
Firebase - Push Notifications
  1. CometChat dashboard: Go to Notifications → Settings, enable Push Notifications, click Add Credentials (FCM), upload the Firebase service account JSON (Project settings → Service accounts → Generate new private key), and copy the Provider ID.
Enable Push Notifications
From the same screen, click Add Provider to upload the Firebase service account JSON. This is how you can Generate a new private key from Firebase:
Upload FCM service account JSON
  1. App constants: Note down your CometChat App ID, Auth Key, and Region from the CometChat dashboard and keep them available to be added to your project’s AppCrendentials.kt. Similarly, note the FCM Provider ID generated in the CometChat dashboard and add the same in your AppConstants.kt; this will be when registering the FCM token with CometChat.

2. Add dependencies (Gradle)

Use a version catalog and aliases (Update applicationId, package names, icons, and app name.). Also, if you are new to CometChat, please review the Maven repositories and related setup requirements before proceeding.
This TOML file defines versions and aliases for the required dependencies.
  • Apply the google-services plugin and place google-services.json in the same module; keep viewBinding enabled if you copy UI Kit screens directly from the sample.
  • Update applicationId, package names, icons, and app name as needed.

3. Manifest permissions and services

Start from the sample AndroidManifest.xml:
  • Permissions cover notifications + telecom; services/receiver wire Firebase delivery (FCMService), notification actions (FCMMessageBroadcastReceiver), and telecom UI (CometChatVoIPConnectionService). Point android:name to your MyApplication.
  • Set android:name on <application> to your MyApplication subclass.
  • Keep runtime permission prompts for notifications, mic, camera, and media access (see AppUtils.kt / HomeActivity.kt in the sample).

4. Application wiring, sample code, and callbacks

  • Clone/open the reference repo.
  • Copy into your app module (keep structure):
    • fcm/fcm for services/DTOs/notification utils/broadcast receiver.
    • fcm/voip for ConnectionService + VoIP helpers.
    • fcm/utils for MyApplication, AppUtils, AppConstants, AppCredentials.
    • Copy String values from res/values/strings.xml.
    • BuildConfig file build.gradle.
  • Update packages to your namespace; set AppCredentials (App ID/Auth Key/Region) and AppConstants.FCMConstants.PROVIDER_ID to your dashboard provider. Point <application android:name> and services/receivers to your package; update app name/icons as needed.
  • Keep notification constants from AppConstants.kt; rename channels/keys consistently if you change them.
What the core pieces do
  • FCMService – receives FCM data/notification messages, parses CometChat payload, and hands off to FCMMessageBroadcastReceiver.
  • FCMMessageBroadcastReceiver – builds grouped notifications, inline reply actions, and routes taps/deeplinks to your HomeActivity.
  • Repository.registerFCMToken – fetches the FCM token and registers it with CometChat using AppConstants.FCMConstants.PROVIDER_ID; call after login.
  • Repository.acceptCall/rejectCall/rejectCallWithBusyStatus – performs server-side call actions so the caller sees the correct state even if your UI is backgrounded.
  • MyApplication – initializes UIKit, manages websocket connect/disconnect, tracks foreground state, and shows/dismisses incoming call overlays.
  • CometChatVoIPConnectionService – handles Android telecom integration so call pushes display a system-grade incoming call UI and cleanly end/busy on reject.
Splash/entry deep link handler (adapt activity targets):
This reads the push extras, clears the summary notification, and forwards the payload to HomeActivity so taps or deep links land in the right screen. SplashViewModel (init UIKit + login check)
Loads credentials from shared prefs, builds UIKitSettings, initializes CometChat UIKit (without auto socket), sets sample metadata, and exposes loginStatus so the splash can route to login vs home. Repository (push token + call helpers)
Thin wrappers that register/unregister FCM tokens with your Provider ID and perform server-side call actions (accept/reject/busy) so the caller sees the correct state even if your UI is backgrounded. MyApplication (push/call lifecycle essentials)
Initializes UIKit/Firebase, adds call listeners, manages websocket connect/disconnect tied to app foreground, tracks the current activity, and caches temp call state so banners can reappear after resume. State to set at runtime:
  • isAppInForeground/currentActivity inside lifecycle callbacks.
  • currentOpenChatId when a chat screen opens; clear on exit to suppress notifications only for the active chat.
  • tempCall via setTempCall(...) when an incoming call arrives; clear on dismiss/end. getTempCall() is read on resume to re-show the banner.

5. Application wiring and permissions

  • AppUtils.kt + your entry screen (e.g., HomeActivity): request notification/mic/camera/storage permissions early.
  • In HomeActivity, keep the VoIP permission chain and phone-account enablement so call pushes can render the native UI:
Requests notification + telecom permissions in sequence, initializes the VoIP phone account, and maps notification payload extras to set currentOpenChatId so you don’t alert for the chat currently open.

6. Register the FCM token after login

Call registration right after CometChatUIKit.login() succeeds:
Registers the current device token with CometChat under your Provider ID after login so the backend can target this user via FCM; retry on failure and rerun when the token rotates. Re-register on token refresh. Keep the provider ID aligned to the FCM provider you created for this app. Handle FCM refresh tokens too:
Ensures a rotated FCM token is re-bound to the logged-in user; without this, pushes will stop after Firebase refreshes the token.

7. Unregister the token on logout

8. Badge count

CometChat’s Enhanced Push Notification payload includes an unreadMessageCount field (a string) representing the total unread messages across all conversations for the logged-in user. You can use this to set the app icon badge and enrich local notifications.

8.1 Enable unread badge count on the CometChat Dashboard

  1. Go to CometChat Dashboard → Notification Engine → Settings → Preferences → Push Notification Preferences.
  2. Scroll to the bottom and enable the Unread Badge Count toggle.
This ensures CometChat includes the unreadMessageCount field in every push payload sent to your app.

8.2 Add the ShortcutBadger dependency

Add the ShortcutBadger library to your app-level build.gradle:

8.3 Expected payload format

CometChat sends FCM data messages with this structure (relevant fields):
unreadMessageCount is a string representing the total unread messages across all conversations for the logged-in user.

8.4 Update the app badge from the push payload

Inside your notification service (for example FCMService.onMessageReceived), parse unreadMessageCount and update the badge:
ShortcutBadger uses launcher-specific APIs (Samsung, Huawei, Xiaomi, etc.) to display a badge number on the app icon. Passing 0 clears the badge.

8.5 Show unread count in the notification

Update your notification builder to display the unread count in the notification itself:
  • setNumber(count) displays a count badge on the notification icon.
  • setSubText() shows the unread count below the notification title.

8.6 Clear badge when the app opens

Clear the badge count when the app launches and every time it resumes from the background. Override onResume() in your main activity:
This ensures the badge is cleared when the user opens the app, keeping the badge count in sync with the actual unread state.

9. Handle message pushes

  • FCMService.onMessageReceived checks message.data["type"].
  • For type == "chat": mark delivered (CometChat.markAsDelivered), skip notifying if the chat is already open (MyApplication.currentOpenChatId), and build grouped notifications (avatars + BigText) via FCMMessageNotificationUtils with inline reply actions.
  • FCMMessageBroadcastReceiver handles inline replies, initializes the SDK headlessly, sends the reply, and refreshes the notification.
  • In your messaging service (e.g., FCMService), set the notification tap intent to your splash/entry activity (e.g., SplashActivity), and keep the currentOpenChatId check to suppress notifications for the open chat.

10. Handle call pushes (ConnectionService)

  • For type == "call", FCMService.handleCallFlow parses FCMCallDto and routes to the voip package.
  • CometChatVoIP registers a PhoneAccount and triggers TelecomManager.addNewIncomingCall for native full-screen UI with Accept/Decline.
  • Busy logic: if already on a call, reject with busy (Repository.rejectCallWithBusyStatus). Cancel/timeout pushes end the active telecom call when IDs match.
  • Runtime VoIP checks: before handling call pushes, request READ_PHONE_STATE, MANAGE_OWN_CALLS, and ANSWER_PHONE_CALLS at runtime and ensure the phone account is enabled (CometChatVoIP.hasEnabledPhoneAccountForVoIP).
  • Foreground suppression: the sample ignores VoIP banners if MyApplication.isAppInForeground() is true; keep or remove based on your UX.
  • Cancel/unanswered handling: on callAction of cancelled/unanswered, end the active telecom call if the session IDs match.

11. Customize notification text or parse payloads

Parse the push into a BaseMessage for deep links:
Parses the CometChat message JSON shipped in the payload into a BaseMessage so you can navigate to the right conversation/thread without extra API calls. Override the push body before sending:
Adds a pushNotification field in metadata so CometChat uses your custom text as the push body for that message.

12. Navigation from notifications

Notification taps launch SplashActivity; it reads NOTIFICATION_PAYLOAD extras and opens the correct user or group in MessagesActivity. Keep launchMode settings that allow the intent extras to arrive.

13. Testing checklist

  1. Install on a physical device and grant notification + mic permissions (Android 13+ needs POST_NOTIFICATIONS).
  2. Log in and ensure token registration succeeds (check Logcat).
  3. Send a message from another user:
    • Foreground: grouped notification shows unless you are already in that chat.
    • Background/terminated: tap opens the correct conversation.
  4. Inline reply from the shade delivers the message and updates the notification.
  5. Trigger an incoming call push:
    • Native full-screen call UI appears with caller info.
    • Accept/Decline work; cancel/timeout dismisses the telecom call.
  6. Reinstall or clear app data to confirm token re-registration works.

Troubleshooting