Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion calls/flutter/voip-calling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
VoIP calling differs from [basic in-app ringing](/calls/flutter/ringing) by leveraging platform-native call frameworks to:
- Show incoming calls on lock screen with system UI
- Handle calls when app is in background or killed
- Integrate with Bluetooth, car systems, and wearables

Check warning on line 15 in calls/flutter/voip-calling.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

calls/flutter/voip-calling.mdx#L15

Did you really mean 'wearables'?
- Provide consistent call experience across devices

```mermaid
Expand All @@ -38,7 +38,7 @@
- [CometChat Chat SDK](/sdk/flutter/overview) and [Calls SDK](/calls/flutter/setup) integrated
- Push notifications configured for both platforms:
- [Firebase Cloud Messaging (FCM)](/notifications/android-push-notifications) for Android
- [APNs](/notifications/ios-apns-push-notifications) for iOS
- [APNs](/notifications/ios-push-notifications) for iOS
- [Push notifications enabled](/notifications/push-overview) in CometChat Dashboard

<Warning>
Expand Down Expand Up @@ -90,8 +90,8 @@
| Component | Platform | Purpose |
|-----------|----------|---------|
| `FirebaseMessagingService` | Android | Receives push notifications for incoming calls when app is in background |
| `ConnectionService` | Android | Android Telecom framework integration — manages call state with the system |

Check warning on line 93 in calls/flutter/voip-calling.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

calls/flutter/voip-calling.mdx#L93

Did you really mean 'Telecom'?
| `PushKit` / APNs | iOS | Receives VoIP push notifications to wake the app |

Check warning on line 94 in calls/flutter/voip-calling.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

calls/flutter/voip-calling.mdx#L94

Did you really mean 'APNs'?
| `CallKit` | iOS | Displays native iOS call UI on lock screen and in-app |
| Method Channel | Flutter | Bridges native call events to Dart code |

Expand Down Expand Up @@ -178,13 +178,13 @@

---

## iOS: APNs + CallKit Integration

Check warning on line 181 in calls/flutter/voip-calling.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

calls/flutter/voip-calling.mdx#L181

Did you really mean 'APNs'?

On iOS, incoming VoIP calls are delivered via Apple Push Notification service (APNs) with VoIP push certificates. CallKit provides the native iOS call UI.

Check warning on line 183 in calls/flutter/voip-calling.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

calls/flutter/voip-calling.mdx#L183

Did you really mean 'APNs'?

### Step 1: Enable Capabilities

In Xcode, enable the following capabilities for your iOS target:

Check warning on line 187 in calls/flutter/voip-calling.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

calls/flutter/voip-calling.mdx#L187

Did you really mean 'Xcode'?
- **Push Notifications**
- **Background Modes** → Voice over IP, Remote notifications

Expand Down
44 changes: 30 additions & 14 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -6505,22 +6505,26 @@
{
"tab": "Push",
"pages": [
"notifications/push-overview",
{
"group": "Getting Started",
"group": "Overview",
"pages": [
"notifications/push-overview",
"notifications/push-getting-started"
]
},
{
"group": "Platform Integrations",
"pages": [
"notifications/android-push-notifications",
"notifications/ios-apns-push-notifications",
"notifications/ios-fcm-push-notifications",
"notifications/flutter-push-notifications-android",
"notifications/flutter-push-notifications-ios",
"notifications/ios-push-notifications",
"notifications/flutter-push-notifications",
"notifications/react-native-push-notifications-android",
"notifications/react-native-push-notifications-ios",
"notifications/web-push-notifications"
]
},
{
"group": " ",
"group": "Settings",
"pages": [
"notifications/preferences",
"notifications/templates-and-sounds",
Expand Down Expand Up @@ -7122,15 +7126,31 @@
},
{
"source": "/extensions/ios-fcm-push-notifications",
"destination": "/notifications/ios-fcm-push-notifications"
"destination": "/notifications/ios-push-notifications"
},
{
"source": "/extensions/ios-apns-push-notifications",
"destination": "/notifications/ios-apns-push-notifications"
"destination": "/notifications/ios-push-notifications"
},
{
"source": "/notifications/ios-apns-push-notifications",
"destination": "/notifications/ios-push-notifications"
},
{
"source": "/notifications/ios-fcm-push-notifications",
"destination": "/notifications/ios-push-notifications"
},
{
"source": "/extensions/flutter-push-notifications",
"destination": "/notifications/flutter-push-notifications-android"
"destination": "/notifications/flutter-push-notifications"
},
{
"source": "/notifications/flutter-push-notifications-android",
"destination": "/notifications/flutter-push-notifications"
},
{
"source": "/notifications/flutter-push-notifications-ios",
"destination": "/notifications/flutter-push-notifications"
},
{
"source": "/extensions/react-native-push-notifications",
Expand Down Expand Up @@ -8512,10 +8532,6 @@
"destination": "https://assets.cometchat.io/legacy-docs/ai-chatbots/ai-bots/bots.html",
"source": "/ai-chatbots/ai-bots/bots"
},
{
"destination": "https://assets.cometchat.io/legacy-docs/notifications/push-notifications-extension-legacy.html",
"source": "/notifications/flutter-push-notifications"
},
{
"destination": "https://assets.cometchat.io/legacy-docs/sdk/ionic-legacy/additional-message-filtering.html",
"source": "/sdk/ionic-legacy/additional-message-filtering"
Expand Down
6 changes: 2 additions & 4 deletions notifications.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,9 @@ canonical: "https://cometchat.com/docs"

<CardGroup cols={4}>
<Card title="Android" icon={<img src="/images/icons/android.svg" alt="Android" />} href="/notifications/android-push-notifications" horizontal />
<Card title="iOS (APNS)" icon={<img src="/images/icons/swift.svg" alt="iOS (APNS)" />} href="/notifications/ios-apns-push-notifications" horizontal />
<Card title="iOS (FCM)" icon={<img src="/images/icons/swift.svg" alt="iOS (FCM)" />} href="/notifications/ios-fcm-push-notifications" horizontal />
<Card title="iOS" icon={<img src="/images/icons/swift.svg" alt="iOS" />} href="/notifications/ios-push-notifications" horizontal />

<Card title="Flutter (Android)" icon={<img src="/images/icons/flutter.svg" alt="Flutter (Android)" />} href="/notifications/flutter-push-notifications-android" horizontal />
<Card title="Flutter (iOS)" icon={<img src="/images/icons/flutter.svg" alt="Flutter (iOS)" />} href="/notifications/flutter-push-notifications-ios" horizontal />
<Card title="Flutter" icon={<img src="/images/icons/flutter.svg" alt="Flutter" />} href="/notifications/flutter-push-notifications" horizontal />
<Card title="React Native (Android)" icon={<img src="/images/icons/react.svg" alt="React Native (Android)" />} href="/notifications/react-native-push-notifications-android" horizontal />
<Card title="React Native (iOS)" icon={<img src="/images/icons/react.svg" alt="React Native (iOS)" />} href="/notifications/react-native-push-notifications-ios" horizontal />
<Card title="Web" icon={<img src="/images/icons/react.svg" alt="Web" />} href="/notifications/web-push-notifications" horizontal />
Expand Down
120 changes: 10 additions & 110 deletions notifications/android-push-notifications.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
- **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.

Check warning on line 36 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L36

Did you really mean 'Gradle'?

## 1. Prepare Firebase and CometChat

Expand All @@ -43,64 +43,20 @@
<img src="/images/firebase-push-notifications.png" alt="Firebase - Push Notifications" />
</Frame>

2. **CometChat dashboard**: Go to **Notifications → Settings**, enable **Push Notifications**, click **Add Credentials** (FCM), enter a **Provider ID** (a unique identifier you choose), and upload the Firebase service account JSON (Project settings → Service accounts → Generate new private key).
## 1. Add the dependency

<Frame>
<img src="/images/80a520bb-pushnotification-enable-e64632d479a2ebba111453b95bd522c6.png" alt="Enable Push Notifications" />
</Frame>

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:

<Frame>
<img src="/images/c6447647-pushnotification-fcm-68092b02a5361d51ba14b09289da3a78.png" alt="Upload FCM service account JSON" />
</Frame>

3. **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 you set 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.

<Tabs>
<Tab title="TOML (libs.versions.toml)">

```toml lines
[versions]
minSdk = "26"
compileSdk = "35"
targetSdk = "35"
agp = "8.7.0"
kotlin = "2.0.0"
googleServices = "4.4.2"
cometChatUikit = "5.2.6"
cometChatSdk = "4.1.8"
cometChatCalls = "4.3.2"
firebaseBom = "33.7.0"
coreKtx = "1.13.1"
appcompat = "1.7.0"
material = "1.12.0"
gson = "2.11.0"
glide = "4.16.0"

[libraries]
cometchat-uikit = { group = "com.cometchat", name = "chat-uikit", version.ref = "cometChatUikit" }
cometchat-sdk = { group = "com.cometchat", name = "chat-sdk-android", version.ref = "cometChatSdk" }
cometchat-calls = { group = "com.cometchat", name = "calls-sdk-android", version.ref = "cometChatCalls" }
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" }
firebase-messaging = { group = "com.google.firebase", name = "firebase-messaging" }
firebase-auth = { group = "com.google.firebase", name = "firebase-auth" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
google-services = { id = "com.google.gms.google-services", version.ref = "googleServices" }
```kotlin settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://dl.cloudsmith.io/public/cometchat/cometchat/maven/")
}
}
```

This TOML file defines versions and aliases for the required dependencies.
Expand Down Expand Up @@ -193,7 +149,7 @@
</application>
```

- Permissions cover notifications + telecom; services/receiver wire Firebase delivery (`FCMService`), notification actions (`FCMMessageBroadcastReceiver`), and telecom UI (`CometChatVoIPConnectionService`). Point `android:name` to your `MyApplication`.

Check warning on line 152 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L152

Did you really mean 'telecom'?

Check warning on line 152 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L152

Did you really mean 'telecom'?

- 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).
Expand All @@ -207,7 +163,7 @@
- `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.

Check warning on line 166 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L166

Did you really mean 'namespace'?
- Keep notification constants from [`AppConstants.kt`](https://github.com/cometchat/cometchat-uikit-android/blob/v5/sample-app-kotlin%2Bpush-notification/src/main/java/com/cometchat/sampleapp/kotlin/fcm/utils/AppConstants.kt); rename channels/keys consistently if you change them.

**What the core pieces do**
Expand All @@ -215,9 +171,9 @@
- `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.

Check warning on line 174 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L174

Did you really mean 'backgrounded'?
- `MyApplication` – initializes UIKit, manages websocket connect/disconnect, tracks foreground state, and shows/dismisses incoming call overlays.

Check warning on line 175 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L175

Did you really mean 'UIKit'?
- `CometChatVoIPConnectionService` – handles Android telecom integration so call pushes display a system-grade incoming call UI and cleanly end/busy on reject.

Check warning on line 176 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L176

Did you really mean 'telecom'?

**Splash/entry deep link handler** (adapt activity targets):

Expand Down Expand Up @@ -247,7 +203,7 @@

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)**

Check warning on line 206 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L206

Did you really mean 'UIKit'?

```kotlin lines
class SplashViewModel : ViewModel() {
Expand Down Expand Up @@ -294,7 +250,7 @@
}
```

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.

Check warning on line 253 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L253

Did you really mean 'prefs'?

Check warning on line 253 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L253

Did you really mean 'UIKit'?

**Repository (push token + call helpers)**

Expand All @@ -320,7 +276,7 @@
}
```

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.

Check warning on line 279 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L279

Did you really mean 'backgrounded'?

**MyApplication (push/call lifecycle essentials)**

Expand Down Expand Up @@ -418,7 +374,7 @@
## 5. Application wiring and permissions

- [`AppUtils.kt`](https://github.com/cometchat/cometchat-uikit-android/blob/v5/sample-app-kotlin%2Bpush-notification/src/main/java/com/cometchat/sampleapp/kotlin/fcm/utils/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:

Check warning on line 377 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L377

Did you really mean 'enablement'?

```kotlin lines
override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -493,7 +449,7 @@
}
```

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.

Check warning on line 452 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L452

Did you really mean 'telecom'?

## 6. Register the FCM token after login

Expand Down Expand Up @@ -539,63 +495,7 @@
}
```

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

```kotlin lines
CometChatNotifications.unregisterPushToken(object : CometChat.CallbackListener<String?>() {
override fun onSuccess(s: String?) { /* success */ }
override fun onError(e: CometChatException) { /* handle error */ }
})
// Then call CometChatUIKit.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 → Notifications → 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`:

```gradle lines
dependencies {
implementation 'me.leolin:ShortcutBadger:1.1.22@aar'
}
```

### 8.3 Expected payload format

CometChat sends FCM data messages with this structure (relevant fields):

```json
{
"data": {
"unreadMessageCount": "5",
"title": "New Message",
"alert": "John: Hello!",
"conversationId": "user_abc123",
"conversationType": "user"
}
}
```

`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:

```kotlin lines
import me.leolin.shortcutbadger.ShortcutBadger
Unregister **before** logout so the device stops receiving pushes for that user:

Check warning on line 498 in notifications/android-push-notifications.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

notifications/android-push-notifications.mdx#L498

Did you really mean 'Unregister'?

// Inside onMessageReceived, after receiving the message:
val unreadCountStr: String? = message.data["unreadMessageCount"]
Expand Down
Loading