diff --git a/docs.json b/docs.json
index a17e6202..b8cd38d9 100644
--- a/docs.json
+++ b/docs.json
@@ -5033,7 +5033,9 @@
"pages": [
"notifications/push-overview",
"notifications/push-integration",
- "notifications/push-customization"
+ "notifications/push-customization",
+ "notifications/android-push-notifications-flutter",
+ "notifications/ios-push-notifications-flutter"
]
},
{
diff --git a/images/firebase-push-notifications.png b/images/firebase-push-notifications.png
new file mode 100644
index 00000000..2187ffde
Binary files /dev/null and b/images/firebase-push-notifications.png differ
diff --git a/images/push-notifications-guide-1.png b/images/push-notifications-guide-1.png
new file mode 100644
index 00000000..86f69f53
Binary files /dev/null and b/images/push-notifications-guide-1.png differ
diff --git a/images/push-notifications-guide-2.png b/images/push-notifications-guide-2.png
new file mode 100644
index 00000000..48c6b220
Binary files /dev/null and b/images/push-notifications-guide-2.png differ
diff --git a/images/push-notifications-guide-3.png b/images/push-notifications-guide-3.png
new file mode 100644
index 00000000..a43dd6af
Binary files /dev/null and b/images/push-notifications-guide-3.png differ
diff --git a/images/push-notifications-guide-4.png b/images/push-notifications-guide-4.png
new file mode 100644
index 00000000..1a9a799d
Binary files /dev/null and b/images/push-notifications-guide-4.png differ
diff --git a/notifications/android-push-notifications-flutter.mdx b/notifications/android-push-notifications-flutter.mdx
new file mode 100644
index 00000000..71a1b200
--- /dev/null
+++ b/notifications/android-push-notifications-flutter.mdx
@@ -0,0 +1,222 @@
+---
+title: "Android Push Notifications (Flutter UI Kit)"
+description: "End-to-end walkthrough for recreating the CometChat push + CallKit-style experience from the Flutter UI Kit sample on Android."
+---
+
+The Flutter UI Kit push-notification demo already solves FCM permissions, background handlers, full-screen incoming-call UI, and navigation from terminated state. This guide distills that reference implementation so you can bring the exact experience into any Flutter app that uses CometChat UI Kit and Calls UI Kit.
+
+
+ Browse the full push-notification sample (Flutter + native Android glue) to diff or copy files.
+
+
+
+The steps below refer to the folder names inside the sample repo (for example
+lib/notifications,
+android/app/src/main/kotlin/com/cometchat/sampleapp/flutter/android/MainActivity.kt, or
+android/app/src/main/AndroidManifest.xml).
+Copy the same structure into your project and only change identifiers (applicationId/package name, provider IDs) to match your app.
+
+
+## Architecture map
+
+| Sample path | Role inside the app | What to copy/replicate |
+| --- | --- | --- |
+| [`lib/notifications`](https://github.com/cometchat/cometchat-uikit-flutter/tree/v5/sample_app_push_notifications/lib/notifications) | Models, platform services, FCM helpers, CallKit-style handlers | Copy the directory as-is when starting a new app; keep folder names so imports resolve. |
+| [`lib/main.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/main.dart) | Initializes Firebase + local notifications, caches `NotificationLaunchHandler`, defines the `callMain` entrypoint for lock-screen calls | Reuse the launch sequence so notification taps from a terminated state reach Flutter before `runApp`. |
+| [`lib/dashboard.dart` / `lib/guard_screen.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/dashboard.dart) | Boots CometChat UI Kit, requests permissions, registers Call/Notification listeners | Mirror the lifecycle hooks to initialize `FirebaseService` only once and capture pending notification taps. |
+| [`lib/notifications/services/android_notification_service/firebase_services.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/notifications/services/android_notification_service/firebase_services.dart) | FCM init, background handler, token registration via `PNRegistry`, and CallKit event bridge | Keep the background handler at top level and ensure provider IDs are set before registering tokens. |
+| [`android/app/src/main`](https://github.com/cometchat/cometchat-uikit-flutter/tree/v5/sample_app_push_notifications/android/app/src/main) | Manifest permissions, MethodChannel glue in `MainActivity.kt`, lock-screen `CallActivity`, and `CallActionReceiver` for accept/decline intents | Start from the sample files, then update `applicationId`, channel names, and icons to match your app. |
+
+## 1. Prerequisites
+
+- Firebase project with an Android app configured (package name matches your `applicationId`) and Cloud Messaging enabled; `google-services.json` inside `android/app`.
+- CometChat app credentials (App ID, Region, Auth Key) plus Push Notification extension enabled with an **FCM provider** created for Flutter Android.
+- Flutter 3.24+ / Dart 3+, the latest CometChat UI Kit (`cometchat_chat_uikit`) and Calls UI Kit (`cometchat_calls_uikit`) packages.
+- Physical Android device for testing—full-screen call notifications and background delivery are unreliable on emulators.
+
+## 2. Prepare credentials before coding
+
+### 2.1 Firebase Console
+
+1. Register your Android package name (the same as `applicationId` in `android/app/build.gradle`) and download `google-services.json` into `android/app`.
+2. Enable Cloud Messaging and copy the Server key if you want to send test messages manually.
+
+
+
+
+
+### 2.2 CometChat dashboard
+
+1. Turn on the **Push Notifications** extension (V2).
+
+
+
+
+
+2. Create an FCM provider for Flutter Android and copy the generated provider ID.
+
+
+
+
+
+### 2.3 Local configuration file
+
+Update [`lib/app_credentials.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/app_credentials.dart) so it exposes your credentials and provider IDs:
+
+```dart
+class AppCredentials {
+ static String _appId = "YOUR_APP_ID";
+ static String _authKey = "YOUR_AUTH_KEY";
+ static String _region = "YOUR_REGION";
+ static String _fcmProviderId = "FCM-PROVIDER-ID";
+}
+```
+
+The sample persists these values to `SharedPreferences`; `saveAppSettingsToNative()` passes them to Android so `CallActionReceiver` can reject calls even if Flutter is not running.
+
+## 3. Bring the notification stack into Flutter
+
+### 3.1 Copy [`lib/notifications`](https://github.com/cometchat/cometchat-uikit-flutter/tree/v5/sample_app_push_notifications/lib/notifications)
+
+- Clone or download the sample once.
+- Copy the entire `lib/notifications` directory (models, Android/iOS services, helpers) into your app.
+- Update the import prefixes (for example replace `package:sample_app_push_notifications/...` with your own package name). Keeping the same folder names avoids manual refactors later.
+
+### 3.2 Wire the entry points
+
+**[`lib/main.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/main.dart)**
+
+- Initialize `SharedPreferencesClass`, `FlutterLocalNotificationsPlugin`, and Firebase before calling `runApp`.
+- Cache `NotificationLaunchHandler.pendingNotificationResponse` when the app is launched from a tapped notification while terminated.
+- Keep the `callMain` entrypoint; `CallActivity` uses it to render the ongoing-call UI over the lock screen.
+
+**[`lib/guard_screen.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/guard_screen.dart) / [`lib/dashboard.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/dashboard.dart) (or your first screen after login)**
+
+- Ensure `CometChatUIKit.init()` and `CometChatUIKit.login()` finish before rendering the dashboard.
+- On Android, instantiate `FirebaseService` and call `notificationService.init(context)` once; on iOS, keep `APNSService`.
+- Replay `NotificationLaunchHandler.pendingNotificationResponse` after the widget tree builds so taps from a killed app still navigate to `MessagesScreen`.
+- Forward lifecycle changes to `IncomingCallOverlay` / `BoolSingleton` to hide stale overlays when the app resumes.
+- `VoipNotificationHandler.handleNativeCallIntent(context)` runs after the first frame to act on accept/decline actions that were tapped from the Android notification before Flutter started.
+
+### 3.3 Align dependencies and configuration
+
+Mirror the sample `pubspec.yaml` versions (update as needed when newer releases ship):
+
+```yaml
+dependencies:
+ firebase_core: ^3.9.0
+ firebase_messaging: ^15.1.6
+ flutter_local_notifications: ^18.0.0
+ flutter_callkit_incoming:
+ path: ../sample_app_push_notifications/flutter_callkit_incoming
+ cometchat_chat_uikit: ^5.2.5
+ cometchat_calls_uikit: ^5.0.11
+ permission_handler: ^11.3.1
+ shared_preferences: ^2.2.1
+```
+
+Run `flutter pub get`, then `flutterfire configure` if you still need to generate `firebase_options.dart`.
+
+## 4. Configure the native Android layer
+
+### 4.1 Gradle + Firebase
+
+1. Add `google-services.json` to `android/app`.
+2. Ensure `android/app/build.gradle` applies the plugins used in the sample:
+
+```gradle
+plugins {
+ id "com.android.application"
+ id "com.google.gms.google-services"
+ id "kotlin-android"
+ id "dev.flutter.flutter-gradle-plugin"
+}
+```
+
+Set `applicationId` to your package name and keep `minSdk 24` or higher. `compileSdk 36` / `targetSdk 35` match the sample but can be raised if your project already targets a newer API.
+
+### 4.2 Manifest permissions and components
+
+Use the sample [`AndroidManifest.xml`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/android/app/src/main/AndroidManifest.xml) as a baseline:
+
+- Permissions for notifications, audio/video, and lock-screen call UI: `POST_NOTIFICATIONS`, `RECORD_AUDIO`, `CAMERA`, `FOREGROUND_SERVICE`, `USE_FULL_SCREEN_INTENT`, `WAKE_LOCK`, `SHOW_WHEN_LOCKED`, `TURN_SCREEN_ON`, and `SYSTEM_ALERT_WINDOW`.
+- `MainActivity` uses `launchMode="singleTask"` with `android:showWhenLocked="true"` / `android:turnScreenOn="true"` so incoming calls can wake the screen.
+- `CallActivity` is a dedicated entrypoint (uses `callMain`) to render the ongoing call over the lock screen and is excluded from recents.
+- `CallActionReceiver` listens to `flutter_callkit_incoming` actions (and mirrored app-specific actions) so Accept/Decline from the native notification reach Flutter.
+- Set `default_notification_icon` meta-data to your icon if you change the launcher asset.
+
+### 4.3 Kotlin bridge for call intents
+
+- [`MainActivity.kt`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/android/app/src/main/kotlin/com/cometchat/sampleapp/flutter/android/MainActivity.kt) exposes a `MethodChannel("com.cometchat.sampleapp")` that supports:
+ - `get_initial_call_intent` – read and clear any call intent extras so `VoipNotificationHandler.handleNativeCallIntent` in Dart can react after Flutter launches.
+ - `setupLockScreenForCall` / `restoreLockScreenAfterCall` – temporarily bypass and then restore the lock screen when a call is accepted.
+ - `saveAppSettings` – stores your App ID and Region for the broadcast receiver.
+- [`CallActionReceiver.kt`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/android/app/src/main/kotlin/com/cometchat/sampleapp/flutter/android/CallActionReceiver.kt) wakes the app for Accept/Decline actions. On decline, it can initialize the CometChat SDK headlessly (using the saved App ID/Region) to reject the call as busy even if Flutter is not running.
+- [`CallActivity.kt`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/android/app/src/main/kotlin/com/cometchat/sampleapp/flutter/android/CallActivity.kt) overrides `getDartEntrypointFunctionName` to `callMain`, letting the ongoing-call UI render in its own activity with lock-screen flags.
+
+If you change the MethodChannel name in Kotlin, update `voipPlatformChannel` inside [`lib/notifications/services/save_settings_to_native.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/notifications/services/save_settings_to_native.dart) to match.
+
+## 5. Token registration and runtime events
+
+### 5.1 FCM tokens
+
+`FirebaseService.init` requests notification permission, sets the background handler (`firebaseMessagingBackgroundHandler`), and registers tokens:
+
+```dart
+final token = await FirebaseMessaging.instance.getToken();
+if (token != null) {
+ PNRegistry.registerPNService(token, true, false); // platform: FCM_FLUTTER_ANDROID
+}
+FirebaseMessaging.instance.onTokenRefresh.listen(
+ (token) => PNRegistry.registerPNService(token, true, false),
+);
+```
+
+`PNRegistry` pulls the provider ID from `AppCredentials.fcmProviderId`. Call this only after `CometChatUIKit.login` succeeds.
+
+### 5.2 Local notifications and navigation
+
+- `LocalNotificationService.showNotification` renders a high-priority local notification when the incoming CometChat message does not belong to the currently open conversation.
+- `NotificationLaunchHandler.pendingNotificationResponse` caches taps triggered while the app is terminated; `dashboard.dart` replays it after navigation is ready.
+- `LocalNotificationService.handleNotificationTap` fetches the user/group and pushes `MessagesScreen` when a notification is tapped from foreground, background, or terminated states.
+
+### 5.3 Call events (VoIP-like pushes)
+
+- The top-level `firebaseMessagingBackgroundHandler` shows the incoming-call UI by calling `VoipNotificationHandler.displayIncomingCall`, which uses `flutter_callkit_incoming` to render a full-screen notification.
+- `FirebaseService.initializeCallKitListeners` binds `FlutterCallkitIncoming.onEvent` so Accept/Decline/Timeout actions map to `VoipNotificationHandler.acceptVoipCall`, `declineVoipCall`, or `endCall`.
+- `VoipNotificationHandler.handleNativeCallIntent` reads Accept/Decline extras passed from `CallActionReceiver` via the MethodChannel if the user acted before Flutter started.
+- `saveAppSettingsToNative()` runs during `FirebaseService.init` to persist App ID/Region for the native receiver; keep it in place or `CallActionReceiver` cannot initialize CometChat when rejecting a call from the lock screen.
+
+## 6. Testing checklist
+
+1. Run on a physical Android device. Grant notification, microphone, and camera permissions when prompted (Android 13+ requires `POST_NOTIFICATIONS`).
+2. From the CometChat Dashboard, send a standard message notification. Verify:
+ - Foreground: a local notification banner shows (unless you are in that chat).
+ - Background: FCM notification appears; tapping opens the right conversation.
+3. Force-quit the app, send another message push, tap it, and confirm `NotificationLaunchHandler` launches `MessagesScreen`.
+4. Trigger an incoming CometChat call. Ensure:
+ - The full-screen call UI shows caller name/type with Accept/Decline.
+ - Accepting on the lock screen notifies Flutter (`handleNativeCallIntent`), starts the call session, and dismisses the native UI when the call ends.
+ - Declining from the notification triggers `CallActionReceiver` to reject the call server-side.
+5. Rotate through Wi-Fi/cellular and reinstall the app to confirm token registration works after refresh events.
+
+## 7. Troubleshooting tips
+
+| Symptom | Quick checks |
+| --- | --- |
+| No notifications received | Confirm `google-services.json` is in `android/app`, the package name matches Firebase, and notification permission is granted (Android 13+). |
+| Token registration errors | Double-check `AppCredentials.fcmProviderId` and that `PNRegistry.registerPNService` runs after login. |
+| Call actions never reach Flutter | Ensure `CallActionReceiver` is declared in the manifest, MethodChannel names match `voipPlatformChannel`, and `VoipNotificationHandler.handleNativeCallIntent` is called from `dashboard.dart`. |
+| Full-screen call UI not showing | Verify `USE_FULL_SCREEN_INTENT`, `WAKE_LOCK`, and `SHOW_WHEN_LOCKED` permissions plus `android:showWhenLocked="true"` / `android:turnScreenOn="true"` on `MainActivity` and `CallActivity`. |
+| Tapping notification from killed app does nothing | Keep the `NotificationLaunchHandler` logic in `main.dart` and replay it after the navigator key is ready (post-frame callback). |
+
+## Additional resources
+
+- [Flutter push-notification sample app (GitHub)](https://github.com/cometchat/cometchat-uikit-flutter/tree/v5/sample_app_push_notifications)
+- [CometChat Push Notification extension docs](/notifications/push-integration.mdx)
+- [Flutter UI Kit quickstart](https://www.cometchat.com/docs/ui-kit/flutter/getting-started)
+- [Android connection service reference](/notifications/android-connection-service.mdx)
diff --git a/notifications/ios-push-notifications-flutter.mdx b/notifications/ios-push-notifications-flutter.mdx
new file mode 100644
index 00000000..24091373
--- /dev/null
+++ b/notifications/ios-push-notifications-flutter.mdx
@@ -0,0 +1,223 @@
+---
+title: "iOS Push Notifications (Flutter UI Kit)"
+description: "End-to-end walkthrough for recreating the CometChat push + CallKit experience from the Flutter UI Kit sample."
+---
+
+The Flutter UI Kit push-notification demo already solves permission prompts, Firebase/APNs registration, PushKit, and CallKit synchronization. This guide distills that reference implementation so you can bring the exact experience into any Flutter app that uses CometChat UI Kit and Calls UI Kit.
+
+
+ Browse the full push-notification sample (Flutter + native iOS glue) to diff or copy files.
+
+
+
+The steps below refer to the folder names inside the sample repo (for example
+lib/notifications
+or
+ios/Runner/AppDelegate.swift).
+Copy the same structure into your project and only change identifiers (bundle ID, provider IDs, package name) to match your app.
+
+
+## Architecture map
+
+| Sample path | Role inside the app | What to copy/replicate |
+| --- | --- | --- |
+| [`lib/notifications`](https://github.com/cometchat/cometchat-uikit-flutter/tree/v5/sample_app_push_notifications/lib/notifications) | Models, platform services, push registry helpers, MethodChannel bridge handlers | Copy the directory as-is when starting a new app; keep the folder boundaries so imports resolve. |
+| [`lib/main.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/main.dart) | Initializes Firebase, SharedPreferences, local notifications, and wires `APNSService.setupNativeCallListener` | Reuse the launch sequence so notification taps from a terminated state reach Flutter before `runApp`. |
+| [`lib/dashboard.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/dashboard.dart) / [`lib/guard_screen.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/guard_screen.dart) | Boots CometChat UI Kit, requests permissions, registers Call/Notification listeners | Mirror the lifecycle hooks to initialize `APNSService` only once and capture pending notification taps. |
+| [`ios/Runner/AppDelegate.swift`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/ios/Runner/AppDelegate.swift) | PushKit + CallKit bridge plus MethodChannel glue for VoIP token + call events | Start from the sample file and update the bundle identifiers or localized strings. |
+| [`lib/notifications/services/pn_registry.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/notifications/services/pn_registry.dart) | Wraps `CometChatNotifications.registerPushToken` for APNs, VoIP, and FCM | Supply your CometChat provider IDs so registration works in every environment. |
+
+## 1. Prerequisites
+
+- Apple Developer account with Push Notifications, Background Modes, and VoIP entitlements for your bundle ID.
+- Firebase project with an iOS app configured (`GoogleService-Info.plist` inside the Runner target) and Cloud Messaging enabled.
+- CometChat app credentials (App ID, Region, Auth Key) plus Push Notification extension enabled with APNs + VoIP providers created.
+- Flutter 3.24+ / Dart 3+, the latest CometChat UI Kit (`cometchat_chat_uikit`) and Calls UI Kit (`cometchat_calls_uikit`) packages.
+- Physical iPhone or iPad for testing—simulators cannot receive VoIP pushes or present CallKit UI.
+
+## 2. Prepare credentials before coding
+
+### 2.1 Apple Developer portal
+
+1. Generate an APNs Auth Key (`.p8`) and note the **Key ID** and **Team ID**.
+2. Enable Push Notifications plus Background Modes → *Remote notifications* and *Voice over IP* on the bundle ID.
+3. Create a VoIP Services certificate/key if you want separate credentials.
+
+### 2.2 Firebase Console
+
+1. Register the same bundle ID and download `GoogleService-Info.plist`.
+2. Enable Cloud Messaging and, if needed, APNs authentication key under *Project Settings → Cloud Messaging*.
+
+### 2.3 CometChat dashboard
+
+1. Turn on the **Push Notifications** extension (V2).
+
+
+
+
+
+2. Create one provider for APNs device pushes and (optionally) another for VoIP pushes.
+
+
+
+
+
+3. Copy the generated provider IDs—they are required inside `CometChatConfig`.
+
+
+
+### 2.4 Local configuration files
+
+Update [`lib/cometchat_config.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/cometchat_config.dart) (or your own config file) so it exposes:
+
+```dart
+class CometChatConfig {
+ static const appId = "YOUR_APP_ID";
+ static const region = "YOUR_APP_REGION";
+ static const authKey = "YOUR_AUTH_KEY";
+ static const fcmProviderId = "FCM-PROVIDER-ID";
+ static const apnProviderId = "APNS-PROVIDER-ID";
+ static const apnVoipProviderId = "APNS-VOIP-PROVIDER-ID"; // optional but recommended
+}
+```
+
+## 3. Bring the notification stack into Flutter
+
+### 3.1 Copy [`lib/notifications`](https://github.com/cometchat/cometchat-uikit-flutter/tree/v5/sample_app_push_notifications/lib/notifications)
+
+- Clone or download the sample once.
+- Copy the entire [`lib/notifications`](https://github.com/cometchat/cometchat-uikit-flutter/tree/v5/sample_app_push_notifications/lib/notifications) directory (models, Android/iOS services, helpers) into your app.
+- Update the import prefixes (for example replace `package:flutter_application_demo/...` with your own package name). Keeping the same folder names avoids manual refactors later.
+
+### 3.2 Wire the entry points
+
+**[`lib/main.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/main.dart)**
+
+- Initialize `SharedPreferencesClass`, Firebase, and `FlutterLocalNotificationsPlugin` before calling `runApp`.
+- Store `NotificationLaunchHandler.pendingNotificationResponse` when the app is opened by tapping a notification while terminated.
+- On iOS, call `APNSService.setupNativeCallListener(context)` from `initState` so Flutter reacts when the native CallKit UI changes state.
+
+**[`lib/guard_screen.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/guard_screen.dart) / [`lib/dashboard.dart`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/lib/dashboard.dart) (or your first screen after login)**
+
+- Ensure `CometChatUIKit.init()` and `CometChatUIKit.login()` finish before rendering the dashboard.
+- Instantiate `APNSService` (iOS only) and call `apnsService.init(context)` inside `initState`.
+- Register CometChat UI + Calls listeners (`CometChatUIEventListener`, `CometChatCallEventListener`, and `CallListener`) exactly once per session; the sample stores the listener IDs inside `APNSService`.
+- Replay `NotificationLaunchHandler.pendingNotificationResponse` after the widget tree builds so taps from a killed app still navigate to `MessagesScreen`.
+- Forward lifecycle changes to `IncomingCallOverlay` / `BoolSingleton` to hide stale overlays when the app resumes.
+
+### 3.3 Align dependencies and configuration
+
+Mirror the sample `pubspec.yaml` versions (update as needed when newer releases ship):
+
+```yaml
+dependencies:
+ firebase_core: ^3.0.0
+ firebase_messaging: ^15.0.0
+ flutter_apns_x: ^2.1.1
+ flutter_callkit_incoming: ^2.0.3+3
+ flutter_local_notifications: ^16.0.0
+ cometchat_chat_uikit: ^5.0.0
+ cometchat_calls_uikit: ^5.0.0
+ permission_handler: ^11.3.0
+```
+
+Run `flutter pub get`, then `flutterfire configure` if you still need to generate `firebase_options.dart`.
+
+## 4. Configure the native iOS layer
+
+### 4.1 Capabilities and Info.plist
+
+1. Open `ios/Runner.xcworkspace` in Xcode.
+2. Under *Signing & Capabilities*, enable **Push Notifications** and **Background Modes** (Remote notifications + Voice over IP).
+3. Add microphone, camera, Bluetooth, and notification permission strings to `Info.plist`.
+4. Set the development team that has access to the APNs/VoIP keys you generated earlier.
+
+### 4.2 `AppDelegate.swift` bridge
+
+Start from the sample [`ios/Runner/AppDelegate.swift`](https://github.com/cometchat/cometchat-uikit-flutter/blob/v5/sample_app_push_notifications/ios/Runner/AppDelegate.swift) and keep these pieces intact:
+
+- **MethodChannel handshake** – create a channel that both Flutter and Swift know:
+
+```swift
+let appInfoChannel = FlutterMethodChannel(
+ name: "com.flutter_application_demo/ios",
+ binaryMessenger: controller.binaryMessenger
+)
+```
+
+Handle at least `getAppInfo`, `endCall`, `onCallAcceptedFromNative`, and `onCallEndedFromNative`, mirroring the Dart side (`APNSService.setupNativeCallListener`).
+
+- **Firebase + plugin registration** – call `FirebaseApp.configure()` before `GeneratedPluginRegistrant.register(with: self)`.
+- **PushKit** – instantiate `PKPushRegistry`, set `desiredPushTypes = [.voIP]`, and forward the token inside `pushRegistry(_:didUpdate:for:)` via `SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(tokenHex)`.
+- **CallKit** – configure `CXProviderConfiguration`, keep a `CXCallController`, and implement `provider(_:perform: CXAnswerCallAction)` / `provider(_:perform: CXEndCallAction)` so native actions propagate to Flutter.
+- **Incoming push handler** – inside `pushRegistry(_:didReceiveIncomingPushWith:)`, convert the CometChat payload into `flutter_callkit_incoming.Data`, set `extra` with the raw payload, and call `showCallkitIncoming(..., fromPushKit: true)`.
+- **UUID helper** – reuse `createUUID(sessionid:)` to produce valid `UUID`s from long CometChat session IDs; this lets CallKit correlate calls even if the payload string exceeds 32 characters.
+
+If you change the MethodChannel name in Swift, remember to update `APNSService.platform` in Dart to match.
+
+## 5. Token registration and runtime events
+
+### 5.1 Standard APNs tokens
+
+`APNSService` hooks into `FirebaseMessaging.instance.getAPNSToken()` (and `onTokenRefresh`) before calling:
+
+```dart
+await CometChatPushRegistry.register(
+ token: token,
+ isFcm: false,
+ isVoip: false,
+);
+```
+
+This registers the device token against the APNs provider selected in `CometChatConfig.apnProviderId`.
+
+### 5.2 VoIP tokens
+
+- Capture the PushKit token in `AppDelegate.pushRegistry(_:didUpdate:for:)`.
+- Forward it to Flutter via the MethodChannel or register it directly from Swift by invoking `CometChatPushRegistry` through `SwiftFlutterCallkitIncomingPlugin`.
+- If you keep the Dart implementation, emit a MethodChannel call named `onVoipToken` and handle it in `APNSService` by calling `CometChatPushRegistry.register(token: token, isFcm: false, isVoip: true);`.
+
+### 5.3 Local notifications and navigation
+
+- `APNSService._showNotification` displays a local notification when the incoming CometChat message does not belong to the currently open conversation.
+- `LocalNotificationService.handleNotificationTap` parses the payload, fetches the relevant user/group, and pushes `MessagesScreen`.
+- `NotificationLaunchHandler.pendingNotificationResponse` caches taps triggered while the app is terminated; replay it on the dashboard once the UI is ready.
+
+### 5.4 Call events
+
+- `FlutterCallkitIncoming.onEvent` is already wired inside `APNSService` to accept or end calls initiated by CallKit.
+- When native CallKit UI accepts/ends a call, Swift invokes `onCallAcceptedFromNative` / `onCallEndedFromNative` on the MethodChannel; `APNSService` then calls `FlutterCallkitIncoming.setCallConnected` or `CometChat.endCall()` to keep both stacks synchronized.
+
+## 6. Testing checklist
+
+1. Run the app on a physical device in debug first. Grant notification, microphone, camera, and Bluetooth permissions when prompted.
+2. From the CometChat Dashboard, send a standard message notification. Verify:
+ - Foreground: a local notification banner shows (unless you are in that chat).
+ - Background: APNs notification appears, tapping opens the right conversation.
+3. Force-quit the app, send another message push, tap it, and confirm `NotificationLaunchHandler` launches `MessagesScreen`.
+4. Trigger an incoming CometChat call. Ensure:
+ - CallKit UI shows contact name, call type, and Accept/Decline.
+ - Accepting on the lock screen notifies Flutter (`setupNativeCallListener`), starts the call session, and dismisses the native UI when the call ends.
+5. Decline the call and confirm both CallKit and Flutter clean up (`BoolSingleton` resets, overlays dismissed).
+6. Rotate through Wi-Fi/cellular and reinstall the app to confirm token registration works after refresh events.
+
+## 7. Troubleshooting tips
+
+| Symptom | Quick checks |
+| --- | --- |
+| No VoIP pushes | Entitlements missing? Ensure Push Notifications + Background Modes (VoIP) are enabled and the bundle ID matches the CometChat provider. |
+| CallKit UI never dismisses | Make sure `endCall(callUUID:)` reports to `CXProvider`, runs a `CXEndCallAction`, **and** calls `SwiftFlutterCallkitIncomingPlugin.sharedInstance?.endCall`. |
+| Flutter never receives native call events | Confirm the MethodChannel names match between Swift and Dart, and `APNSService.setupNativeCallListener` runs inside `initState`. |
+| Token registration errors | Double-check `CometChatConfig` provider IDs, and verify you call `registerPushToken` after `CometChatUIKit.login` succeeds. |
+| Notification taps ignored | Ensure you replay `NotificationLaunchHandler.pendingNotificationResponse` **after** the navigator key is ready (typically `WidgetsBinding.instance.addPostFrameCallback`). |
+
+## Additional resources
+
+- [Flutter push-notification sample app (GitHub)](https://github.com/cometchat/cometchat-uikit-flutter/tree/v5/sample_app_push_notifications)
+- [CometChat Push Notification extension docs](/notifications/push-integration.mdx)
+- [Flutter UI Kit quickstart](https://www.cometchat.com/docs/ui-kit/flutter/getting-started)
+- [APNs configuration reference](/notifications/ios-apns-push-notifications.mdx)