React Native SDK Guide
React Native bridge, install, join and events.
The React Native SDK has the RtcEngine + IRtcEngineEventHandler shape and is exposed to JS through a native bridge (Kotlin/Java on Android, Objective-C on iOS).
Prerequisites
- React Native 0.74+, Node.js ≥ 22, Xcode 16+ / Android SDK 35.
- Android needs the
CAMERAandRECORD_AUDIOruntime permissions; iOS needsNSCameraUsageDescription/NSMicrophoneUsageDescription. - An
appIdand a token service (see Enable Services and Get Credentials).
Installation
# planned package name, not published to npm yet
npm install react-native-nimeet-rtc
cd ios && pod installExpo projects need a prebuild (npx expo prebuild) before the native module can be added.
Get a token
Your backend issues the token (POST /v1/tokens), and the RN side only keeps { appId, rtcToken, rtcUid }; never bundle customerSecret into the JS bundle.
const { appId, rtcToken, rtcUid } = await fetch('/api/rtc-token?channel=weekly-sync&uid=10001').then(r => r.json());Join a channel
import {
createAgoraRtcEngine,
ChannelProfileType,
ClientRoleType,
IRtcEngineEventHandler,
} from 'react-native-nimeet-rtc';
const engine = createAgoraRtcEngine();
const handler: IRtcEngineEventHandler = {
onJoinChannelSuccess: (connection, elapsed) => console.log('joined', connection.channelId),
onUserJoined: (connection, remoteUid, elapsed) => console.log('remote joined', remoteUid),
onUserOffline: (connection, remoteUid, reason) => console.log('remote left', remoteUid),
onTokenPrivilegeWillExpire: () => refreshToken(),
onError: (err) => console.warn('rtc error', err),
};
engine.initialize({ appId, logConfig: { level: 1 } });
engine.registerEventHandler(handler);
engine.setChannelProfile(ChannelProfileType.ChannelProfileLiveBroadcasting);
engine.enableVideo();
engine.startPreview();
engine.joinChannel(rtcToken, 'weekly-sync', rtcUid, {
clientRoleType: ClientRoleType.ClientRoleBroadcaster,
});Publishing and subscribing
engine.muteLocalAudioStream(true);
engine.muteLocalVideoStream(true);
engine.enableLocalVideo(false);
engine.updateChannelMediaOptions({ clientRoleType: ClientRoleType.ClientRoleAudience });Screen sharing relies on native capability: MediaProjection (with a foreground service) on Android, a Broadcast Upload Extension on iOS; the method names are in this platform's API reference (startScreenCapture, getScreenCaptureSources and so on).
Events
An IRtcEngineEventHandler is a plain object: fill in the methods you need. The common ones: onJoinChannelSuccess, onUserJoined, onUserOffline, onFirstRemoteVideoDecoded, onTokenPrivilegeWillExpire, onError, onConnectionStateChanged.
Error handling
- Synchronous methods return a numeric error code;
0means success and a negative value is an Agora error number; - Asynchronous errors arrive through
onError; - Unimplemented capabilities return
-4(ERR_NOT_SUPPORTED).
Troubleshooting
| Symptom | Cause | Handling |
|---|---|---|
TurboModule error | The version is not adapted to the new architecture | Check the RN version against the package support matrix |
| iOS build fails | Pods are not installed | cd ios && pod install |
| Black screen on Android | Missing runtime permissions | Request CAMERA / RECORD_AUDIO |
| No events after a hot reload | The handler was not registered again | Register when the component mounts and call unregisterEventHandler on unmount |
| Expo Go crashes | Expo Go does not contain the native module | Use a dev client / prebuild |
Next steps
- Full interfaces and overloads: API reference for this platform
- Error codes and troubleshooting: Error code table, FAQ
- Issue tokens on your server: Token authentication
Platform information
| Item | value |
|---|---|
| Platform | React Native |
| Language | TypeScript / Java / Objective-C |
| SDK package | react-native-nimeet-rtc |
| Interface version | 4.6.4 |
| Compatible Agora API | Agora rn API |
The public interfaces are aligned with the Agora rn API; installation and runtime requirements are listed under Prerequisites above.
Availability
This platform's SDK: Generally available. The examples use the public API; runtime capability follows the published SDK package.
join-channel flow
The method names, parameter types and return values match the API reference for the same platform. Where a method has several overloads, the most common one is shown here; see the API reference for all overloads.
| Step | Interface | Method | Overload count |
|---|---|---|---|
| subscribe to remote media | IBaseSpatialAudioEngine | muteRemoteAudioStream | 1 |
| Create instance / initialize | ILocalSpatialAudioEngine | initialize | 1 |
| Renew the Token | IMusicContentCenter | renewToken | 1 |
| enable video and local preview | IRtcEngine | enableVideo | 1 |
| Join a channel | IRtcEngine | joinChannel | 1 |
| Leave a channel | IRtcEngine | leaveChannel | 1 |
| Channel scenarios | IRtcEngine | setChannelProfile | 1 |
| switch roles | IRtcEngine | setClientRole | 1 |
muteRemoteAudioStream(uid: number, mute: boolean): number
initialize(): number
renewToken(token: string): number
enableVideo(): number
joinChannel(token: string, channelId: string, uid: number, options: ChannelMediaOptions): number
leaveChannel(options?: LeaveChannelOptions): number
setChannelProfile(profile: ChannelProfileType): number
setClientRole(role: ClientRoleType, options?: ClientRoleOptions): numberEvents and callbacks
Callbacks are registered on IRtcEngineEventHandler; naming differs by platform, and the full list is in the API reference for the same platform.
| Callbacks | Signature | Purpose |
|---|---|---|
onConnectionStateChanged | onConnectionStateChanged(connection: RtcConnection, state: ConnectionStateType, reason: ConnectionChangedReasonType): void | join result / connection-state changes:update the UI accordingly and decide whether to reconnect. |
onUserJoined | onUserJoined(connection: RtcConnection, remoteUid: number, elapsed: number): void | Remote user joined:allocate the frame container. |
onFirstRemoteVideoDecoded | onFirstRemoteVideoDecoded(connection: RtcConnection, remoteUid: number, width: number, height: number, elapsed: number): void | Remote video status:it can render once the first frame is decoded. |
onUserOffline | onUserOffline(connection: RtcConnection, remoteUid: number, reason: UserOfflineReasonType): void | Remote user left:release the container and subscription. |
onRequestToken | onRequestToken(connection: RtcConnection): void | Token expiring soon:call the server to renew, then `renewToken`. |
onError | onError(err: ErrorCodeType, msg: string): void | Runtime errors:`err` is an Agora error number, route by the error-code table. |
onNetworkQuality | onNetworkQuality(connection: RtcConnection, remoteUid: number, txQuality: QualityType, rxQuality: QualityType): void | Network quality:report to Analytics or prompt the user. |
Error codes
| Constant | value |
|---|---|
ErrAborted | 20 |
ErrAdmGeneralError | 1005 |
ErrAdmInitPlayout | 1008 |
ErrAdmInitRecording | 1011 |
ErrAdmStartPlayout | 1009 |
ErrAdmStartRecording | 1012 |
ErrAdmStopPlayout | 1010 |
ErrAdmStopRecording | 1013 |
ErrAlreadyInUse | 19 |
ErrBitrateLimit | 115 |
ErrBufferTooSmall | 6 |
ErrCertRaw | 1001 |
ErrClientIsBannedByServer | 123 |
ErrConnectionInterrupted | 111 |
ErrConnectionLost | 112 |
ErrDatastreamDecryptionFailed | 122 |
ErrDecryptionFailed | 120 |
ErrEncryptedStreamNotAllowedPublish | 130 |
ErrFailed | 1 |
ErrInitNetEngine | 21 |
ErrInvalidAppId | 101 |
ErrInvalidArgument | 2 |
ErrInvalidChannelName | 102 |
ErrInvalidState | 8 |
ErrInvalidToken | null |
ErrInvalidUserAccount | 134 |
ErrInvalidUserId | 121 |
ErrJoinChannelRejected | 17 |
ErrLeaveChannelRejected | 18 |
ErrNoPermission | 9 |
ErrNoServerResources | 103 |
ErrNotInChannel | 113 |
ErrNotInitialized | 7 |
ErrNotReady | 3 |
ErrNotSupported | 4 |
ErrOk | 0 |
ErrPcmsendBufferoverflow | 201 |
ErrPcmsendFormat | 200 |
ErrRefused | 5 |
ErrResourceLimited | 22 |
ErrSetClientRoleNotAuthorized | 119 |
ErrSizeTooLarge | 114 |
ErrStreamMessageTimeout | 117 |
ErrTimedout | 10 |
ErrTokenExpired | 109 |
ErrTooManyDataStreams | 116 |
ErrVdmCameraNotAuthorized | 1501 |
IRtcEngine | null |
the platform REST layer uses REST error codes;the SDK layer maps connection/authentication failures to Agora error numbers, for the mapping table see SDK error identifiers per platform。