CometChat.initiateCall created the call, a CallListener on the WebSocket told the callee, acceptCall and rejectCall answered, and the app rang the device itself, often with its own FCM, PushKit and CallKit code or flutter_callkit_incoming. Ringing now runs on the Calls SDK and cometchat_voip. The Chat SDK’s calling methods are superseded by the Calls SDK and no longer used; a coming Chat SDK release marks them deprecated.
This page is the diff. For the full description of the current flow see Ringing; for the push side see Push 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 adding these packages doesn’t move them to this flow. This guide applies to your own calling screens and handlers.
Why it changed
Before and after
Step 1: Update dependencies
minSdk 26on Android, and the requirements of Calls SDK 5.1: on iOS it builds with Swift Package Manager only, deployment target 15.1.- Keep
firebase_core,firebase_messagingand your Firebase configuration. - Remove packages you used only to ring calls, such as
flutter_callkit_incoming.
Step 2: Initialize cometchat_voip
Initialize it right after the Calls SDK, from the sameCallAppSettings:
callMode defaults to CometChatCallMode.auto, which is what this page assumes: cometchat_voip rings the call and draws the ring screen. The options are on Push Ringing.
Step 3: Shrink your push handlers
- Before
- After
AppDelegate: cometchat_voip receives VoIP pushes and reports calls to CallKit itself. Keep no PKPushRegistry of your own; a second registry takes the VoIP pushes and those calls never ring.
Step 4: Change the token code
- Before
- After
Step 5: Delete the app-side ringing
Everything in this list is now done bycometchat_voip. Remove it, or it will fight the new ring (two ringtones, two screens, a busy reject sent on top of cometchat_voip’s).
CometChat.addCallListener(...)and itsonIncomingCallReceivedhandler- The incoming call screen, overlay or dialog you showed from it
- Your own ringtone for incoming calls
- The “already in a call, reject with busy” check
- Your call handling with
flutter_callkit_incomingor a CallKit or ConnectionService integration of your own, with its event listeners - Any “app in foreground” check around call pushes
Info.plist.
Step 6: Rewrite the call code
Caller, before and after
- Before
- After
Callee, before and after
- Before
- After
Step 7: Change the logout
- Before
- After
If you drew your own incoming call screen
Keep it, but drive it fromcometchat_voip instead of the CallListener. Set callMode: CometChatCallMode.autoCustomScreen and show your screen from CometChatVoip.onRingScreenRequested; answer with CometChatVoip.answer(sessionId) and decline with CometChatVoip.decline(sessionId). cometchat_voip still rings, times out and sends the decline; only the screen is yours. See Your own ring screen.
What users will notice
- Calls ring with the app killed and on the lock screen.
- The caller sees “Ringing…” once the callee’s phone is reached, and the reason when a call is declined or missed.
- An unanswered call stops ringing after 45 seconds.
- Missed calls appear as notifications on the callee’s phone.
- A call during a call is call waiting (answering ends the current call, declining sends busy), not an automatic reject.
- The microphone and camera prompt appears on Answer the first time, on the phone that answers.
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 andcometchat_voip 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.
acceptOnAnswer on in CometChatVoipConfig (it’s the default). When a user on the new app answers, it also reports the answer the legacy way, so a caller still on the old app joins the call. Turn it off once every caller has the new app.
Checklist
-
cometchat_calls_sdkandcometchat_voipadded;minSdk 26and iOS 15.1 -
cometchat_voipinitialized at app start, inmain - Every push goes to
handlePushNotificationwithmessage.sentTime, in the foreground too - Legacy token registration replaced; on Android the FCM token is handed over on every launch; the token is unregistered before logout
-
CometChat.addCallListener, your own incoming screen, ringtone, busy check and CallKit orflutter_callkit_incomingcode removed -
initiateCallsetstypeand the session settings, withsetPeerCall(true) - The caller listens on the prepared session and on
IncomingCallListener, joins only ononParticipantJoined, and runs a ring timer - The callee joins in
onCallAnswered, without waiting for a screen - Hang-up uses
leave(); noCometChat.endCall - Logout also logs out of the Calls SDK
-
checkRingReadinessruns after login, and anything other thanreadyis shown to the user - Call pushes are sent at high priority
- Connect legacy ringing is on before the release
- Tested on real devices: ring with the app killed, decline, cancel, no answer, a call during a call, logout while ringing