What this guide covers
- Adding the
@cometchat/push-notifications-react-nativepackage and initializing it. - Platform wiring: Firebase/
google-services.jsonon Android, the setup CLI + PushKit forwarding on iOS. - Requesting permission and registering tokens (FCM on Android, APNs + VoIP on iOS) after login.
- Receiving pushes and letting the package render chat notifications and full-screen / CallKit calls.
- Handling notification taps (including thread deep-links), incoming-call navigation, and Android OEM permissions.
- Testing and troubleshooting.
The
@cometchat/push-notifications-react-native package replaces the previous approach of copying the sample app’s notifications stack and hand-wiring @react-native-firebase/messaging, notifee, react-native-callkeep, and react-native-voip-push-notification. Token registration, foreground presentation, notification taps, and the full incoming-call experience (the Android lock-screen call activity and iOS CallKit) are handled inside the package — the design is JS-first: native code only shows the UI and captures tokens, while every CometChat action (register token, accept/reject/end call) runs in JavaScript through the Chat SDK your app already ships.How it works
- Android (FCM): Firebase issues the registration token and delivers the CometChat payload as a data message. The package ships its own
FirebaseMessagingService, so it receives the message and shows the notification or full-screen call itself — you write no FCM handling code. - iOS (APNs + PushKit): Apple issues the APNs device token (chat alerts) and the VoIP token (calls). APNs alerts are shown by the system; VoIP pushes are presented through CallKit by the package. Your
AppDelegateforwards the tokens and incoming VoIP pushes to the package (the setup CLI generates this). - CometChat’s role: The providers you add in the dashboard bind your registered tokens to the logged-in user so CometChat can route pushes on your behalf.
- The package’s role: it retrieves the tokens, registers them with CometChat, parses payloads, drives the call UI, and calls the Chat SDK to accept/reject/end. It requires
@cometchat/chat-sdk-react-nativeas a peer dependency — the one Chat SDK your app already uses, so there is no second SDK to version-align.
Prerequisites
- The providers, Firebase project, and Apple/APNs credentials from Getting Started (this guide assumes those are done).
- React Native 0.65+, and an app already initializing and logging in with
@cometchat/chat-sdk-react-native(or the UI Kit). - Android:
google-services.jsoninandroid/app/, thecom.google.gms.google-servicesplugin,minSdkVersion 24+. - iOS: iOS 13.0+ (set the Podfile platform to 14.0 for VoIP/CallKit).
- A physical device — background delivery, full-screen calls, and VoIP pushes are unreliable on emulators/simulators.
Complete the Getting Started guide first — enable Push Notifications, add your providers (FCM for Android, APNs + APNs VoIP for iOS), and finish the Firebase/Apple setup. This guide covers only the React Native app wiring.
1. Store your credentials
Keep the values from Getting Started somewhere your app can read them. Only the fields for the platforms you ship are needed:2. Add the package and configure the platform
Install the package (the Chat SDK peer is already in your app):- Android
- iOS
With
google-services.json already in android/app/ (from Getting Started):- Apply the Google Services plugin and Firebase Messaging in your Gradle files:
- Keep
minSdkVersion 24or higher.
You do not need to add notification, call, full-screen-intent, or lock-screen permissions to your
AndroidManifest.xml, and you write no FCM/JS message-handling code. The package’s library manifest contributes everything it needs — the FirebaseMessagingService, the incoming-call foreground service, the full-screen lock-screen CallRingingActivity, the notification trampoline/decline receiver, and POST_NOTIFICATIONS — and Gradle merges them into your app automatically.3. Initialize the SDK
Register the killed-state background task at module scope inindex.js (before any component renders), then initialize the package after the user logs in.
init wires the native events to the Chat SDK, auto-registers the device tokens, and drains any cold-start tap/call the app was launched from. It is safe to call again on re-login.
init also accepts: voip (default true), notificationSmallIcon, androidChannelId, and androidChannelName.
4. Request permission and register tokens
Permission is requested viaCometChatPNHelper (call it before pushes/calls arrive):
init() registers the FCM token (Android) and the APNs device + VoIP tokens (iOS) with CometChat, and re-registers on refresh. You rarely need to do it by hand, but you can:
Not unsubscribing on logout leaves the callbacks registered, so a logout → login cycle would fire each handler twice (e.g. navigating to a tapped message twice).
5. Notification taps and call events
Subscribe once (insetupPush above). Each subscribe returns an unsubscribe function.
Notification tap — open the conversation, or the thread when the push is a thread reply:
6. Android: OEM permissions for lock-screen calls
The package declares the standard permissions and uses the correctsetShowWhenLocked / setTurnScreenOn flags, so full-screen calls over the lock screen work out of the box on stock Android (including Android 14+). OEM skins (MIUI/Redmi/POCO, Oppo, Vivo) additionally gate background-launched full-screen activities behind their own toggles — without them, a locked/killed call shows only a heads-up notification (with ringtone), and the full-screen screen appears only after unlock.
Guide users to grant, on those devices:
- Autostart — Settings → Apps → your app → Autostart (or the Security app).
- Display pop-up windows while running in background — Settings → Apps → your app → Other permissions.
- Show on lock screen — same “Other permissions” screen.
- Disable battery optimization for the app.
7. Badge count
CometChat’s Enhanced Push payload includes anunreadMessageCount field (total unread across conversations).
- iOS
- Android
With APNs the badge is handled server-side: CometChat sets
aps.badge in the payload and iOS updates the app icon automatically — no client code required.8. Testing checklist
- Run on a physical device. Grant notification, microphone, and camera permissions when prompted (Android 13+ requires
POST_NOTIFICATIONS). - Send a message from another user:
- Foreground: no system banner (with
showInForeground: false); your in-app UI shows it. - Background: a notification appears; tapping opens the right conversation via
onNotificationTap(and the thread, for a thread reply).
- Foreground: no system banner (with
- Force-quit the app, send another message, tap the notification, and confirm it cold-starts to the conversation.
- Trigger an incoming CometChat call and confirm:
- The full-screen call UI (Android) / CallKit (iOS) shows the caller with Accept/Decline, even on the lock screen.
- Accept joins the call (audio works both ways) and the screen tears down when the call ends.
- Decline rejects the call promptly on the caller side — including from a killed state.
- Caller cancels while it’s ringing → the callee ring dismisses.
- On an OEM device (MIUI/Oppo/Vivo), grant the section-6 permissions and re-check locked/killed calls.
9. Troubleshooting
Resources
@cometchat/push-notifications-react-native
The drop-in push & VoIP package on npm.
@cometchat/chat-sdk-react-native
The peer Chat SDK the package registers tokens and drives calls through.