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:
- React Native WebRTC
- React Native WebRTC handbook
- Twilio Video overview
- Twilio Video access tokens
- Apple PushKit VoIP notifications
Choose the Calling Backend
Instamobile apps have historically supported two approaches:
| Option | Best for | Backend requirement |
|---|---|---|
| WebRTC with Firebase signaling | Direct app-to-app calling and full source control | Firebase/Firestore signaling plus your own STUN/TURN configuration. |
| Twilio Video | Managed video rooms, access tokens, diagnostics, and Twilio media services | Backend 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 module | Purpose |
|---|---|
IMAudioVideoChat | Coordinates incoming, outgoing, accepted, and ended call states. |
AudioChatView | Audio-call UI after a call starts. |
VideoChatView | Video-call UI after a video call starts. |
| Firebase or call API module | Signaling operations when Firebase is used. |
| App config | Public call endpoints and feature flags. |
audioVideoChat reducer/state | Stores 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
.voipsuffix 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:
- Copy the audio/video module folder.
- Copy required reducers or state providers.
- Copy required native dependencies.
- Add camera, microphone, notification, and call permissions.
- Configure Firebase signaling or Twilio token server.
- Configure iOS PushKit/CallKit if incoming calls must work in the background.
- Configure Android FCM/CallKeep if incoming calls must work in the background.
- 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
| Problem | Fix |
|---|---|
| Calls never connect | Check signaling writes, participant permissions, ICE candidates, and TURN configuration. |
| Works on Wi-Fi but not mobile data | Add or fix TURN servers. STUN alone is not enough for all networks. |
| iOS background calls do not appear | Check PushKit token, APNs credentials, CallKit reporting, bundle ID, and real-device testing. |
| Android locked-screen calls do not appear | Check FCM delivery, notification permission, CallKeep/ConnectionService setup, and OEM battery restrictions. |
| Twilio token endpoint fails | Check backend environment variables, API key permissions, token TTL, and authenticated user identity. |
| App Store review questions PushKit usage | Be ready to show that PushKit is used only for real incoming calls and that CallKit is displayed. |