Reference implementation
Browse the full React Native push sample (UI Kit + Calls + VoIP).
Architecture map
| Sample path | Role | What to copy/replicate |
|---|---|---|
App.tsx | Initializes CometChat UI Kit, requests permissions, registers tokens, handles foreground FCM, and navigates on notification taps | Mirror the effects for FCM/APNs/VoIP token handling and Notifee foreground events. |
index.js | Background handlers: FCM setBackgroundMessageHandler, Notifee onBackgroundEvent, and VoIP call actions | Keep the same handlers so taps from killed/background states navigate correctly and call pushes render native UI. |
src/utils/PushNotification.tsx | Thin wrapper around CometChatNotifications.registerPushToken / unregisterPushToken for FCM + APNs/VoIP | Reuse for token registration; update provider IDs. |
src/utils/helper.ts | FCM token retrieval, local notifications via Notifee, iOS initial/tap handling, deep links into chats | Copy the helper and keep the navigation logic for conversation routing. |
src/utils/VoipNotificationHandler.ts | RNCallKeep + Notifee bridge for incoming call UI (Android/iOS) and call actions | Use as-is; ensure Android phone account permissions/capabilities and iOS CallKit permissions are configured. |
src/utils/AppConstants.tsx | Stores App ID/Region/Auth Key and fcmProviderId / apnProviderId | Fill with your credentials and provider IDs from the dashboard. |
ios/SampleAppWithPushNotifications/AppDelegate.swift | Native glue for iOS: Firebase/UNUserNotificationCenter delegates, PushKit VoIP token, CallKeep incoming calls | Copy the delegates and PushKit setup so FCM/APNs/VoIP events reach JS and CallKeep renders incoming calls. |
1. Prerequisites
- CometChat app credentials (App ID, Region, Auth Key) and Push Notifications extension enabled with FCM provider (React Native) and APNs provider created; copy both provider IDs.
- Firebase project with Android app configured (
google-services.jsoninandroid/app) and FCM enabled. - Apple push setup: APNs certificate/keys configured in CometChat, iOS project with Push Notifications + Background Modes (Remote notifications, VoIP) + CallKit permissions.
- React Native 0.81+, Node 18+, physical devices for reliable push/call testing.
- Native deps from the sample:
@react-native-firebase/messaging,@react-native-firebase/app,@notifee/react-native,@react-native-community/push-notification-ios,react-native-voip-push-notification,react-native-callkeep, and CometChat UI Kit + Calls SDK.
Push Notification extension settings (dashboard)
- Set Extension version to
V2(orV1 & V2while migrating). - Select Platforms: enable React Native Android + iOS (and others you use).
- Use Payload trimming if you risk exceeding ~4 KB (strip metadata or trim text).
- Toggle Notification triggers (messages, calls, groups) to match your app.
2. Project setup (sample parity)
2.1 Credentials
- Update
src/utils/AppConstants.tsxwithappId,authKey,region,fcmProviderId, andapnProviderId. - Keep
app.jsonname consistent with your bundle ID / applicationId.
2.2 Gradle + Firebase (Android)
- Place
google-services.jsoninandroid/app. - Apply
com.google.gms.google-servicesinandroid/app/build.gradle(the sample already does). - Ensure
minSdk/targetSdkmatch your project (sample uses RN 0.81 defaults). - Grant notification + call permissions in the manifest (POST_NOTIFICATIONS, RECORD_AUDIO, CAMERA, READ_PHONE_STATE, FOREGROUND_SERVICE, ANSWER_PHONE_CALLS, USE_FULL_SCREEN_INTENT, WAKE_LOCK, VIBRATE).
2.3 iOS capabilities
- Enable Push Notifications + Background Modes (Remote notifications, VoIP).
- Add CallKit usage descriptions to
Info.plist(microphone/camera) and configurereact-native-callkeepper sampleios/folder. - Add your APNs auth key/cert in the CometChat dashboard provider.
2.4 Dependencies snapshot (from sample)
3. Wire up push tokens
3.1 Register tokens with CometChat
registerPushToken maps platform + provider ID to CometChatNotifications.registerPushToken:
3.2 Android (FCM)
getAndRegisterFCMToken(helper.ts) runs after login and registers the token;messaging().onTokenRefreshre-registers on rotation.- Foreground messages:
messaging().onMessageinApp.tsxshows a Notifee notification viadisplayLocalNotificationunless that chat is open. - Background/terminated:
messaging().setBackgroundMessageHandlerinindex.jsshows Notifee notifications for chats or triggers VoIP call UI whendata.type === 'call'.
3.3 iOS (APNs + VoIP)
PushNotificationIOS.requestPermissionsrequests alert/badge/sound.- APNs device token:
PushNotificationIOS'register'event callshandleIosApnsTokento register with CometChat. - VoIP token:
react-native-voip-push-notification'register'event callshandleIosVoipToken;VoipPushNotification.registerVoipToken()is triggered after APNs registration. - Taps + initial opens:
checkInitialNotificationIOSandonRemoteNotificationIOSfetch the user/group and navigate toMessageswith parent threads when present. - AppDelegate.swift changes (native iOS):
- Add
UNUserNotificationCenterDelegateto forward APNs callbacks toRNCPushNotificationIOS. - Register PushKit (
PKPushRegistrywith.voIP) and forward VoIP tokens toRNVoipPushNotificationManager.didUpdate. - In
pushRegistry(_:didReceiveIncomingPushWith:), mapcallActionvalues toRNCallKeep.reportNewIncomingCall/endCallso VoIP pushes show native CallKit UI when the app is backgrounded/killed. - Keep
RNVoipPushNotificationManager.voipRegistration()indidFinishLaunchingand setUNUserNotificationCenter.current().delegate = self.
- Add
3.4 Logout / cleanup
CallCometChat.logout() and unregisterPushToken() when signing out; delete FCM token if you want to force a fresh registration on next login.
4. Message notifications
- Notifee foreground notifications (
displayLocalNotification) skip the current open chat and include avatars, BigText, and conversation metadata for navigation. - Notifee background presses are handled in
index.jsandApp.tsx(foreground) to navigate vianavigateToConversation. - iOS notifications deliver
data.messageanddata.parentId; helpers fetch the user/group before navigation. - To turn a push payload back into a CometChat object for custom UI, use:
5. Call notifications (VoIP-like)
- FCM
data.type === "call"is handled inindex.jsbackground handler: call actions (initiated,cancelled,rejected,busy,ended,unanswered,ongoing) driveVoipNotificationHandler. VoipNotificationHandleruses CallKeep to show native incoming call UI and manage telecom permissions;PendingCallManagerresumes accepted calls if the app was cold-started.- Android foreground calls still arrive via FCM; ensure phone account permissions are granted or CallKeep cannot render the incoming screen.
6. Customizing the push body
Setmetadata.pushNotification before sending to override the body:
7. Testing checklist
- Android: install on device, grant POST_NOTIFICATIONS; log in and verify FCM token registration success.
- Send a chat push from CometChat Dashboard:
- Foreground: Notifee banner shows unless that chat is open.
- Background/terminated: tap opens the correct conversation; Notifee background handler runs.
- iOS: verify APNs device token + VoIP token register; tap push from killed app opens the right chat; remote notifications finish handler is called.
- Trigger incoming call push: native CallKeep UI should show caller info; Accept/Decline routes to the app and clears CallKeep state on cancel/end.
- Rotate tokens (reinstall or revoke) and confirm
onTokenRefreshre-registers.
8. Troubleshooting
| Symptom | Quick checks |
|---|---|
| No pushes | Confirm google-services.json location, package/bundle IDs match Firebase/Apple, Push extension enabled with correct provider IDs, permissions granted. |
| Token registration fails | Ensure registration runs after login, provider IDs are set, and registerDeviceForRemoteMessages() is called (Android). |
| Notification taps do nothing | Keep Notifee foreground/background handlers and checkInitialNotificationIOS; ensure navigation ref is ready before routing. |
| Call UI not showing | Verify CallKeep setup, telecom permissions (Android) or CallKit entitlement (iOS), and that VoipNotificationHandler.initialize() runs post-login. |
| Inline reply needed | Extend Notifee action buttons; CometChat expects you to send the message manually after reading remoteMessage.data. |