Skip to main content
Legacy ringing signalled calls through the Chat SDK: CometChat.initiateCall created the call, a CallListener on the WebSocket told the callee, acceptCall and rejectCall answered, and the app rang the device itself — usually with react-native-callkeep and react-native-voip-push-notification wired up by hand. Ringing now runs on the Calls SDK and the Push Notifications SDK’s VoIP package. The Chat SDK’s calling methods are deprecated. This page is the diff. For the full description of the current flow see Ringing; for the push side see Push ringing.

Before you start

Ringing with the Calls SDK is opt-in on the client: moving your app to the Calls SDK 5.1 and Push Notifications SDK 2.0 APIs below is the migration. While some of your users are still on legacy ringing, one dashboard setting lets the two flows call each other; see While some users are still on legacy ringing. If you use the CometChat UI Kit, keep its calling as it is: the Kit’s call components still use the Chat SDK (CometChat.initiateCall, CometChat.acceptCall), so installing these packages doesn’t move them to this flow. This guide applies to your own calling screens and handlers. See Calling integration.

Why it changed

Before and after

Step 1: Update dependencies

  • minSdkVersion 24 or higher on Android, iOS 15.1+. Below API 26 the ring posts a plain notification rather than the channel-backed, full-screen one.
  • Keep google-services.json. @react-native-firebase/messaging is optional: if you keep it, forward pushes to the package as in section 4.5 of the Android push guide.
  • Remove react-native-callkeep and react-native-voip-push-notification if nothing else uses them; the VoIP package registers with PushKit and CallKit itself.
callMode defaults to 'auto', which is what this page assumes. Installing the VoIP package is the opt-in: the core package detects it and installs the ringer.

Step 2: Replace the push configuration

A calls-only app passes its configuration to CometChatVoipNotifications.init(config) instead and never calls the core’s init. An app that does both must not pass a config to the VoIP init() — that re-runs the core initialisation and drops every chat option.
onCallAccepted and onCallEnded moved packages. In 1.0 they were on CometChatPushNotifications; in 2.0 they are on CometChatVoipNotifications. The old names are gone rather than deprecated, so a call left on the core object throws is not a function — search your app for CometChatPushNotifications.onCall and repoint both.
If your Chat and Calls SDKs point at a staging or dedicated deployment, pass the same host as clientHost. Otherwise the push token registers on the default host and no push ever arrives.

Step 3: Make init() the first thing you await

A cold launch caused by a call push has a ring window measured from the caller’s side. Anything awaited before init() — a stored-credentials read, a remote config fetch, a login — spends that window, and the call is lost before the ring is wired up.

Step 4: Register the background task and delete the token code

index.js
The Push SDK registers the token on login by itself. Unregistering is not automatic — this package installs no logout listener, so call unregister() before you log out (see Step 7). Remove:
  • messaging().getToken() + registerPushToken(...) after login
  • VoipPushNotification.addEventListener('register', …) and the APNs VoIP token plumbing
  • unregisterPushToken(...) before logout — replaced by CometChatPushNotifications.unregister(), which must run before logout()

Step 5: Delete the app-side ringing

Everything in this list is now done by the Push SDK. Remove it, or it will fight the SDK’s ring (two ringtones, two screens, a busy reject sent on top of the SDK’s).
  • CometChat.addCallListener(...) and its onIncomingCallReceived handler
  • The incoming-call modal, overlay or screen you rendered from it
  • Your own ringtone or sound player for incoming calls
  • The “already in a call → reject with busy” check
  • RNCallKeep.setup, displayIncomingCall, answerCall/endCall event wiring, VoipPushNotification handlers, and the READ_PHONE_STATE / MANAGE_OWN_CALLS / ANSWER_PHONE_CALLS permission chain
  • Any foreground check around call pushes
Keep NSMicrophoneUsageDescription, NSCameraUsageDescription and the voip background mode in Info.plist — those are your app’s own and nothing merges them in. You can drop RECORD_AUDIO, CAMERA and POST_NOTIFICATIONS from your Android manifest: the push package declares POST_NOTIFICATIONS, the VoIP package declares the other two, and the manifest merger adds them for you. (An app that installs only the push package gets no call permissions at all — that is the point of the split.)

Step 6: Rewrite the call code

Caller screen, before and after

Callee screen, before and after

Step 7: Change the logout

unregister() after logout() cannot authenticate the delete, so the token stays registered and the device goes on receiving the departed user’s call pushes. Logging out of the Chat SDK alone leaves the Calls SDK signed in, so a ring keeps playing for the old user.

If you drew your own incoming-call screen

You can keep it. Subscribe to onCallRinging instead of CallListener.onIncomingCallReceived, close it from onRingEnded, and answer and decline through CometChatVoipNotifications.answerCall / declineCall. Tell the SDK your screen is up with notifyCallScreenOpen(sessionId) so it does not also show its own. See Your own incoming-call screen. This replaces the in-app screen only. A push that arrives while your app is killed still rings with the SDK’s native screen on Android and CallKit on iOS — neither can be drawn from JavaScript that is not running.

While some users are still on legacy ringing

Your users don’t all update at once, so during the rollout one CometChat app has devices on both flows. A device’s flow comes from its push registration: a device on the Calls SDK 5.1 and Push Notifications SDK 2.0 receives only the call-initiated push, and a device still on legacy ringing keeps receiving the legacy call events. To let users on the two flows call each other, turn on Connect legacy ringing in the CometChat dashboard under Voice & Video Calls → Settings. CometChat then also sends calls made on this flow as legacy call events, so devices on either flow ring for calls from the other.
  • Turn it on before the first users update, and leave it on while any version of your app still in use rings the legacy way.
  • It can’t be turned off from the dashboard.
  • The six legacy call events (ongoing, cancelled, rejected, unanswered, busy and ended) are under Show legacy in Notifications → Settings → Call Preferences. They only reach devices on legacy ringing.
This is a server-side bridge, so it needs no code on either side. A device that has been updated does not need the legacy CallListener back — keep it deleted.

What users will notice

  • Calls now ring with the app killed, and from the lock screen.
  • The caller sees “Ringing…” once the callee’s device has actually been reached, and a reason when a call ends.
  • A second call rings over a live one instead of being silently rejected.
  • Missed calls appear as their own notifications.

Checklist

  • Calls SDK 5.1, Push SDK 2.0 core and VoIP packages installed; CallKeep and VoIP-push libraries removed
  • CometChatVoipNotifications.init() is the first await on startup, and the chat app passes it no config
  • registerBackgroundCallTask() called at module scope in index.js
  • All CometChat.addCallListener call handling, app-side ringtones and busy checks deleted
  • Caller listens on the prepared session for onParticipantConnected / onParticipantJoined
  • onCallAccepted and onCallEnded repointed from CometChatPushNotifications to CometChatVoipNotifications, and subscribed before the first call can arrive
  • Hang-up uses session.leave(), cancel uses endCall(sessionId, 'cancelled')
  • Logout unregisters push first, then clears the identity, then logs out
  • requestCallPermissions() called after sign-in; ensureRingReady() checked; NSMicrophoneUsageDescription present
  • Staging or dedicated host passed to the Push SDK as well
  • Connect legacy ringing turned on in the dashboard before the first users update, if any of your app versions still ring the legacy way
  • All three packages installed: Calls SDK 5.1 and both Push Notifications packages at 2.0