Skip to content
Platform docs
Auth, users, webhooks & more
Info:
This is beta documentation for Stream Video React Native SDK v2. For the latest stable version, see the latest version (v1).

Troubleshooting

This section covers common integration issues that prevent calls from establishing.

Connection issues

Invalid tokens, network issues, or firewalls can prevent WebSocket connections. Always handle call.join() rejections:

try {
  await call.join();
} catch (err) {
  setError(err); // handle error
}

The SDK retries up to three times with exponential backoff. Customize or disable retries:

try {
  await call.join({ maxJoinRetries: 1 }); // disable retries
} catch (err) {
  setError(err); // handle error
}

Connection issues during calls (network switching, poor signal) trigger automatic reconnection. See Network Disruption guide.

Expired tokens

Tokens have expiry dates. Verify token contents at jwt.io.

Provide a tokenProvider when creating StreamVideoClient to automatically refresh expired tokens.

Wrong secret for token generation

Tokens from docs won't work - they're generated with demo app secrets. Generate tokens using your app secret from the dashboard.

Verify token signatures at jwt.io. For development, generate tokens here. Production requires backend token generation.

User-token mismatch

Ensure the token matches the user ID provided to StreamVideoClient.

Ringing call issues

Issues typically manifest as missing incoming call screens or failed notification delivery.

Members of a call

You cannot call yourself. Members must be different users who have connected to Stream at least once (required for device registration and notification delivery).

Reusing a call id

Call IDs can be reused for joining, but ringing only works once per ID. For ringing calls, use unique IDs (e.g., UUIDs).

Push notification integration issues

Troubleshooting steps:

  • Verify no connection issues (see above)
  • Confirm push provider names match setPushConfig configuration
  • Check Webhook & Push Logs in Stream dashboard for failures, and see the push troubleshooting guide to diagnose common delivery errors
  • Use unique call IDs for ringing calls
  • Mount StreamVideo at root level for early event listening
  • Use StreamVideoClient.getOrCreateInstance() instead of new StreamVideoClient()
Info:

During development, you may be facing a situation where push notification is shown but its events like accepting or rejecting a call don't work. This is because, during hot module reloading the global event listeners may get de-registered. To properly test during development, make sure that you fully restart the app or test in release mode without the metro packager.

iOS specific

  • Disable Do Not Disturb and other focuses that block CallKit
  • Verify VoIP certificate matches dashboard bundle ID
  • Confirm app uses correct bundle ID
  • Add Push Notifications Capability in Xcode
  • Enable background modes: processing, remote-notification, voip
  • Test with third-party VoIP notification service
Info:

Note that if you have failed to report a VoIP notification to CallKit, the operating system may stop sending you notifications. In those cases, you need to re-install the app and try again.

Android specific

Logging

SDK logging

Enable verbose logging for debugging call flows. Default level is warn. Options: trace, debug, info, error.

import { StreamVideoClient, Logger } from "@stream-io/video-react-native-sdk";

const client = StreamVideoClient.getOrCreateInstance({
  apiKey,
  token,
  user,
  options: {
    logLevel: "info",
  },
});

WebRTC behaviour logging

Enable native WebRTC logs for debugging media packets and peer connections. View in Android Studio or Xcode.

iOS

AppDelegate.swift
import stream_react_native_webrtc

override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
  let options = WebRTCModuleOptions.sharedInstance()
  options.enableMultitaskingCameraAccess = true
  options.loggingSeverity = .verbose

  // the rest
}

Android

MainApplication.kt
import com.oney.WebRTCModule.WebRTCModuleOptions
import org.webrtc.Logging

override fun onCreate() {
  val options: WebRTCModuleOptions = WebRTCModuleOptions.getInstance()
  options.loggingSeverity = Logging.Severity.LS_VERBOSE

  // the rest
}

Common Errors

Error: "Illegal State: call.join() shall be called only once"

call.join() invoked multiple times, often from component re-renders. Ensure single invocation.

iOS Silent Mode / Audio Not Playing

Audio may not play on iOS when the device is in silent mode.

Android: Incoming calls not ringing when app is in background/killed

Common fixes:

  1. Use singleton client:

    const client = StreamVideoClient.getOrCreateInstance({
      apiKey,
      user,
      token,
    });
  2. Mount <StreamVideo> at app root level

  3. Verify Firebase: FCM handlers, background handler, permissions (POST_NOTIFICATIONS, FOREGROUND_SERVICE)

  4. Grant runtime notification permission on Android 13+

  5. Enable notification channels in system settings

  6. Manually launch force-stopped apps - system limitation blocks push until user interaction. See Ringing Setup guide.

Platform-Specific Issues

iOS Simulator Limitations

iOS Simulator lacks camera/microphone support. Test on physical devices.

Android Battery Drain

Causes: background calls, persistent WebSocket connections, idle foreground services.

End calls when backgrounding:

useEffect(() => {
  const subscription = AppState.addEventListener("change", (state) => {
    if (state === "background" && !isInCall) {
      client.disconnectUser();
    }
  });

  return () => subscription.remove();
}, [isInCall]);

Run foreground services only during active calls. See Keeping Call Alive.