Skip to main content

Video Chat

Video chat is an optional core module. Use this guide only if your app includes audio/video calling or you are adding calling to another Instamobile app.

Quick Answer

Calling requires more than UI components. You need a signaling layer, media transport, real-device permissions, backend secrets, and platform-specific incoming-call behavior. Keep WebRTC/Twilio credentials on the backend, test iOS PushKit with CallKit, test Android incoming-call behavior with FCM and CallKeep, and verify every call state on real devices before release.

Official references:

Choose the Calling Backend

Instamobile apps have historically supported two approaches:

OptionBest forBackend requirement
WebRTC with Firebase signalingDirect app-to-app calling and full source controlFirebase/Firestore signaling plus your own STUN/TURN configuration.
Twilio VideoManaged video rooms, access tokens, diagnostics, and Twilio media servicesBackend token server with Twilio API key and secret.

Do not enable both implementations unless your product intentionally supports both. Pick one implementation, remove dead config from the UI, and validate the native dependencies for that path.

Twilio previously announced an end-of-life plan for Programmable Video, then reversed that decision in a Twilio changelog. Still, check Twilio's current product and SDK support before committing to a production architecture.

Source Map

Depending on the app package generation date, video chat files may live under one of these paths:

src/core/chat/audioVideo
src/core/video

Search the app:

rg "IMAudioVideoChat|AudioChatView|VideoChatView|Twilio|WebRTC|CallKeep|PushKit|audioVideo" src

Common pieces:

File or modulePurpose
IMAudioVideoChatCoordinates incoming, outgoing, accepted, and ended call states.
AudioChatViewAudio-call UI after a call starts.
VideoChatViewVideo-call UI after a video call starts.
Firebase or call API moduleSignaling operations when Firebase is used.
App configPublic call endpoints and feature flags.
audioVideoChat reducer/stateStores active call state for the main app shell.

WebRTC with Firebase Signaling

With this approach, Firebase is used for signaling, not for media. The media stream is negotiated through WebRTC.

Production requirements:

  • Firestore rules restrict who can create, read, update, and delete call signals.
  • Signaling documents expire or are cleaned up after calls end.
  • Call participants are validated server-side or through strict Firestore rules.
  • STUN/TURN servers are owned by you or by a vendor you control.
  • TURN credentials are not public demo credentials.
  • Calls are tested across Wi-Fi, mobile data, and poor network conditions.

Do not ship old public TURN credentials from sample code. Use your own TURN provider if users must call through restrictive networks.

Twilio Video

With Twilio Video, users join Twilio Rooms with short-lived access tokens generated by your backend.

Backend requirements:

  • Twilio Account SID or API key lives only on the backend.
  • Twilio API Key Secret lives only on the backend.
  • Access tokens are short-lived.
  • Token endpoint authenticates the signed-in user.
  • Room names are generated or validated by the backend.
  • Room creation, completion, and webhooks are monitored.

Mobile config should point to your token endpoint:

export const TWILIO_SERVER_ENDPOINT =
'https://your-backend.example.com/getTwilioAccessToken';

Deploy the token server as Firebase Functions, Cloud Run, Heroku, Render, or another HTTPS backend. Do not place Twilio API secrets in React Native source code.

iOS Incoming Calls: PushKit and CallKit

iOS incoming calls require native behavior when the app is backgrounded, locked, or not running.

Production requirements:

  • PushKit is configured only for real VoIP call notifications.
  • CallKit is used to present the incoming call UI.
  • Your server sends VoIP APNs notifications to the PushKit token.
  • The VoIP push topic matches your bundle identifier with the .voip suffix when required by your APNs setup.
  • The app reports the incoming call to CallKit promptly after receiving a VoIP push.
  • APNs credentials are stored securely on the backend or in the APNs provider service.

Apple requires VoIP pushes to be tied to actual call behavior. Do not use PushKit for generic notifications.

Android Incoming Calls: FCM and CallKeep

Android background or locked-screen call behavior usually depends on Firebase Cloud Messaging and native call integration through CallKeep or a similar ConnectionService integration.

Production requirements:

  • FCM works before testing call pushes.
  • Android notification runtime permission is handled.
  • Phone account or ConnectionService setup is tested.
  • Foreground, background, and killed-state behavior is tested on real devices.
  • The app handles denied permissions gracefully.

Integrating the Module into Another App

If you copy the video chat module into another React Native app:

  1. Copy the audio/video module folder.
  2. Copy required reducers or state providers.
  3. Copy required native dependencies.
  4. Add camera, microphone, notification, and call permissions.
  5. Configure Firebase signaling or Twilio token server.
  6. Configure iOS PushKit/CallKit if incoming calls must work in the background.
  7. Configure Android FCM/CallKeep if incoming calls must work in the background.
  8. Test on real iOS and Android devices.

Example state integration:

const audioVideoChatConfig = useSelector(state => state.audioVideoChat);

Render the coordinator near the app shell:

{audioVideoChatConfig && <IMAudioVideoChat {...audioVideoChatConfig} />}

Verification Checklist

Test at minimum:

  • caller starts an audio call;
  • caller starts a video call;
  • recipient accepts;
  • recipient declines;
  • caller cancels before answer;
  • either user ends an active call;
  • app receives a call in foreground;
  • app receives a call in background;
  • app receives a call from the locked screen;
  • permissions are denied and the UI handles it;
  • network drops during a call;
  • call state cleans up in Firebase or Twilio after ending.

Troubleshooting

ProblemFix
Calls never connectCheck signaling writes, participant permissions, ICE candidates, and TURN configuration.
Works on Wi-Fi but not mobile dataAdd or fix TURN servers. STUN alone is not enough for all networks.
iOS background calls do not appearCheck PushKit token, APNs credentials, CallKit reporting, bundle ID, and real-device testing.
Android locked-screen calls do not appearCheck FCM delivery, notification permission, CallKeep/ConnectionService setup, and OEM battery restrictions.
Twilio token endpoint failsCheck backend environment variables, API key permissions, token TTL, and authenticated user identity.
App Store review questions PushKit usageBe ready to show that PushKit is used only for real incoming calls and that CallKit is displayed.

Next Steps