RealTimeX
Sign inStart for free
RealTimeXMobile Package
Introduction5-minute overviewFeaturesHow the package worksGlossary
Requirements & dependenciesBackend credentialsInstallation step by stepTutorial — your first chat appProject config fileApp entry — index.jsQuick start — minimum working chatComplete ChatScreen example
Native configuration (iOS & Android)Firebase, APNs & backend setup
Navigation — embedding the chatSession, auth & Socket.IOPermissions & access controlAudio & video callingPush notificationsMentions viewRich-text messages (WebView editor)Total unread count
Customization — four waysDefault component fallback (important)Which slots are wiredCustomization examples (Case 1–4)UI feature flags & copy (ui)Chat info (group + DM)Style overrides (ui.styles)Render props (ChatProvider)Theme, fonts & appearance
ChatProvider props referenceconfigureChat options referenceHooks & storeCallbacks referenceAPI query paramsAll exports
Production integration pattern (Fieldr)Host app integration — providers, toasts, tab bars & navigationEnvironment variablesLocal package / monorepo (Metro)
TroubleshootingSetup checklistArchitectureDocumentation & file mapPackage development (maintainers)License
Mobile packageNative Configuration

Native configuration (iOS & Android)

The package ships every piece of native code that a library can ship. What is left is per-app (bundle ids, signing, Firebase files, entitlements, activity attributes) and cannot be set from a dependency.

What the package does for you

AreaAndroid — android-screenshare/ (autolinked)iOS — RealtimexLiveChat pod (autolinked)
Call permissionsINTERNET, CAMERA, RECORD_AUDIO, MODIFY_AUDIO_SETTINGS, BLUETOOTH (max SDK 30), BLUETOOTH_CONNECT merged into your manifest— (usage strings are yours)
Screen shareSYSTEM_ALERT_WINDOW, FOREGROUND_SERVICE, FOREGROUND_SERVICE_MEDIA_PROJECTION, WAKE_LOCK, VideoSDK notification meta-data and the live.videosdk.rnwebrtc.MediaProjectionService foreground serviceVideosdkRPK (ReplayKit picker bridge); the extension code ships as the RealtimexLiveChatBroadcast pod
Picture-in-PictureCallPipModule — hooks the activity itself, no MainActivity codeCallPipModule
PushPOST_NOTIFICATIONS, USE_FULL_SCREEN_INTENT, VIBRATE; channels rtx_messages, rtx_mentions, rtx_calls (RtxNotifications)—
Ringing calls when killed / lockedRtxCallPushReceiver on com.google.android.c2dm.intent.RECEIVE + Notifee full-screen notificationRealtimexVoip — sets up CallKit and PushKit at launch and reports every VoIP push to CallKit; no AppDelegate code
Token, permission prompt, registration, taps, clears, logoutJavaScript, inside ChatProviderJavaScript, inside ChatProvider

Never copy CallPipModule, VideosdkRPK or RealtimexVoip into your app, and never register a second CallPipPackage in MainApplication — they would be duplicate classes.

Native file cheat sheet

Replace MyChatApp with your Xcode target / Android package. In Fieldr the names are ios/Fieldr/…, ios/FieldrBroadcast/… and com.softwareco.fieldr.

FileWhat you addNeeded for
android/build.gradleclasspath('com.google.gms:google-services:4.4.1')Push
android/app/build.gradleapply plugin: "com.google.gms.google-services"Push
android/app/google-services.jsonFrom the Firebase project connected on the RealtimeX dashboardPush
android/app/src/main/AndroidManifest.xmlandroid:supportsPictureInPicture="true" + android:resizeableActivity="true" on .MainActivityCall PiP
ios/MyChatApp/Info.plistCamera / microphone / photo usage strings, UIBackgroundModes, RTCAppGroupIdentifier, RTCScreenSharingExtensionCalls, push, screen share
ios/MyChatApp/MyChatApp.entitlementsaps-environment, App GroupPush, screen share
ios/MyChatApp/AppDelegate.swiftFirebaseApp.configure()Push
ios/MyChatApp/GoogleService-Info.plistFrom the same Firebase project, added to the app targetPush
ios/Podfilesetup_permissions([...]); Broadcast extension targetPermissions, screen share
ios/MyChatAppBroadcast/3 templates from host-setup/ios/screen-share/Broadcast/Screen share
babel.config.jsreact-native-worklets/pluginAlways
metro.config.jsOnly for local / monorepo installsLocal package
firebase.jsonmessaging_ios_foreground_presentation_options: [] (optional)No duplicate iOS foreground banners
index.jsVideoSDK register(), push options and background handlersCalls, push

Android — android/build.gradle

groovy
1buildscript {2  dependencies {3    // …existing classpaths4    classpath('com.google.gms:google-services:4.4.1')5  }6}

Android — android/app/build.gradle

groovy
1apply plugin: "com.android.application"2apply plugin: "org.jetbrains.kotlin.android"3apply plugin: "com.facebook.react"4apply plugin: "com.google.gms.google-services"   // ← add

Put google-services.json in android/app/.

Android — android/app/src/main/AndroidManifest.xml

Activity attributes are not merged from libraries, so add these two on your launcher activity:

xml
1<activity2  android:name=".MainActivity"3  android:supportsPictureInPicture="true"4  android:resizeableActivity="true"5  ...>

Every permission, service and receiver listed in What the package does for you is merged automatically. Paste host-setup/android/AndroidManifest.snippet.xml only if you disabled Android autolinking for this package.

Optional:

  • Full-screen incoming calls: install @notifee/react-native and set androidFullScreenCalls: true (App entry). Android 14+ grants USE_FULL_SCREEN_INTENT automatically only to calling / alarm apps (Play Console declaration); without it the call shows as a heads-up notification.
  • Notification icon: a white-on-transparent drawable, e.g. android/app/src/main/res/drawable/ic_notification.png, passed as configurePushNotifications({androidSmallIcon: 'ic_notification'}).

MainActivity.kt and MainApplication.kt need no chat code.

iOS — ios/MyChatApp/Info.plist

From host-setup/ios/snippets/Info.plist.snippet.xml, plus the photo-library string for attachments:

xml
1<key>NSCameraUsageDescription</key>2<string>Camera access is required for video calls.</string>3<key>NSMicrophoneUsageDescription</key>4<string>Microphone access is required for audio and video calls.</string>5<key>NSPhotoLibraryUsageDescription</key>6<string>Choose photos and videos to send in chat.</string>7 8<!-- Screen share: must match the App Group and the Broadcast extension bundle id -->9<key>RTCAppGroupIdentifier</key>10<string>group.com.example.mychatapp</string>11<key>RTCScreenSharingExtension</key>12<string>com.example.mychatapp.Broadcast</string>13 14<key>UIBackgroundModes</key>15<array>16  <string>audio</string>               <!-- call audio in the background -->17  <string>voip</string>                <!-- PushKit calls; camera in PiP on iOS 18+ -->18  <string>picture-in-picture</string>  <!-- call PiP -->19  <string>remote-notification</string> <!-- background delivery + clear pushes -->20</array>

Optional VoIP keys:

KeyTypeEffect
RealtimexCallKitOptionsDictionaryCallKit setup overrides: appName (default CFBundleDisplayName), imageName (template image in the asset catalog), ringtoneSound, includesCallsInRecents, supportsVideo
RealtimexVoipAutoSetupBooleanNO turns the pod's PushKit / CallKit bootstrap off, for apps that run PushKit themselves

iOS — ios/MyChatApp/MyChatApp.entitlements

From host-setup/ios/snippets/Entitlements.snippet.plist. In Xcode: Signing & Capabilities → Push Notifications, Background Modes, App Groups.

xml
1<key>com.apple.security.application-groups</key>2<array>3  <string>group.com.example.mychatapp</string>4</array>5<key>aps-environment</key>6<string>development</string>   <!-- Xcode switches to production for release / TestFlight -->

com.apple.developer.avfoundation.multitasking-camera-access (camera in PiP / Split View on iOS 16–17) is a managed entitlement — request it from Apple first; adding it unapproved breaks signing. iOS 18+ only needs the voip background mode.

iOS — ios/MyChatApp/AppDelegate.swift

React Native Firebase requires FirebaseApp.configure() at the start of launch:

swift
1import Firebase2 3// inside application(_:didFinishLaunchingWithOptions:), first line:4FirebaseApp.configure()

No PushKit, CallKit or bridging-header code is needed — the pod's RealtimexVoip handles it. An app delegate that already implements pushRegistry(_:didReceiveIncomingPushWith:for:completion:) keeps working: the pod sees it and stays off (that app must then report every push to CallKit itself — host-setup/ios/snippets/AppDelegate.pushkit.snippet.swift).

iOS — ios/Podfile

ruby
1require_relative '../node_modules/react-native-permissions/scripts/setup'2 3setup_permissions([4  'Camera',5  'Microphone',6  'PhotoLibrary',7])8 9target 'MyChatApp' do10  config = use_native_modules!11  use_react_native!(:path => config[:reactNativePath])12  # …React Native Firebase pod settings for your setup (Fieldr: $RNFirebaseAsStaticFramework = true)13end14 15# Screen share — TOP-LEVEL target, outside the app target.16target 'MyChatAppBroadcast' do17  inherit! :search_paths    # not :none — CocoaPods would then link nothing18  pod 'RealtimexLiveChatBroadcast',19      :path => '../node_modules/@realtimexsco/live-chat-react-native'20end

Then cd ios && pod install.

iOS — screen share extension ios/MyChatAppBroadcast/

  1. Xcode → File → New → Target → Broadcast Upload Extension (MyChatAppBroadcast, no UI extension).
  2. Replace its files with the 3 templates in host-setup/ios/screen-share/Broadcast/:
    • SampleHandler.swift — the whole file is one line of code:
swift
1import RealtimexLiveChatBroadcast2 3class SampleHandler: RealtimexBroadcastSampleHandler {}
  • Info.plist — NSExtensionPointIdentifier com.apple.broadcast-services-upload, RPBroadcastProcessMode RPBroadcastProcessModeSampleBuffer, RTCAppGroupIdentifier.
    • Broadcast.entitlements — the same App Group.
  1. Set the extension PRODUCT_BUNDLE_IDENTIFIER (com.example.mychatapp.Broadcast) and put the same value in the main Info.plist RTCScreenSharingExtension.
  2. Replace group.YOUR_TEAM.YOUR_APP in both Info.plists and both entitlements with your App Group.
  3. Embed the .appex under Embed Foundation Extensions, add the Podfile target above, pod install.

More detail: ios/SCREEN_SHARE_HOST_SETUP.md.

iOS — firebase.json (project root, optional)

The package draws foreground RealtimeX notifications itself. If your app has no UNUserNotificationCenterDelegate, React Native Firebase also presents FCM pushes in the foreground; turn that off to avoid a second banner:

json
{"react-native": {"messaging_ios_foreground_presentation_options": []}}

An app with its own UNUserNotificationCenter delegate should complete remote pushes with [] in willPresent.

Optional patches — patches/ (patch-package)

Patch (copy from host-setup/patches/)When
@videosdk.live+react-native-webrtc+0.0.22.patchYour camera keeps streaming in iOS PiP / iPad multitasking; rounded self-view corners on Android. Fieldr applies it via "postinstall": "patch-package"
react-native-callkeep+4.3.16.patchOnly if you keep your own AppDelegate PushKit code on the New Architecture. Not needed with the pod's RealtimexVoip

Native steps that cannot be moved into the package

StepWhy it stays in the app
google-services.json, GoogleService-Info.plist, Google Services Gradle plugin, FirebaseApp.configure()Per-app Firebase project and bundle id
Push Notifications capability, Background Modes, App GroupEntitlements are signed into the app's provisioning profile
Info.plist usage strings and UIBackgroundModesRead only from the app bundle; the copy is yours (App Store review)
android:supportsPictureInPicture on MainActivityActivity attributes are not merged from libraries
Broadcast Upload Extension targetAn app extension is a separate signed target
react-native-permissions Podfile handlersConfigured in the app's Podfile
APNs auth key in Firebase, Apple VoIP key on the dashboardApple Developer account credentials
Notifee / CallKeep / VoIP push installsNative peers must be app dependencies to autolink

Upgrading from the AppDelegate PushKit snippet

Earlier versions asked hosts to paste PushKit / CallKit code into the AppDelegate. To move to the pod:

  1. Delete the PKPushRegistryDelegate extension, RNCallKeep.setup(...), RNVoipPushNotificationManager.voipRegistration() and import PushKit from AppDelegate.swift.
  2. Delete the bridging-header imports for RNCallKeep / RNVoipPushNotificationManager (and the header with its SWIFT_OBJC_BRIDGING_HEADER setting if it is now empty).
  3. Delete patches/react-native-callkeep+4.3.16.patch.
  4. pod install, rebuild.
PreviousComplete ChatScreen exampleNextFirebase, APNs & backend setup

On this page

What the package does for youNative file cheat sheetAndroid — android/build.gradleAndroid — android/app/build.gradleAndroid — android/app/src/main/AndroidManifest.xmliOS — ios/MyChatApp/Info.plistiOS — ios/MyChatApp/MyChatApp.entitlementsiOS — ios/MyChatApp/AppDelegate.swiftiOS — ios/PodfileiOS — screen share extension ios/MyChatAppBroadcast/iOS — firebase.json (project root, optional)Optional patches — patches/ (patch-package)Native steps that cannot be moved into the packageUpgrading from the AppDelegate PushKit snippet
Back to top