Expo Room Operations
Use mediasfu-reactnative-expo 2.5.0 to add room state, participant
updates, camera and microphone controls, remote-media handling, screen sharing,
and participant exit to an Expo application. This guide gives each operation
its package-specific name and keeps room authority in your application backend.
Before you start
- Use Expo SDK 57 with React Native 0.86, as required by this package.
- Configure microphone and camera permissions for every mobile platform you support, and test capture on physical devices.
- Put room policy, authentication, rate limits, and long-lived MediaSFU credentials in an authenticated HTTPS backend.
- Treat screen sharing as a platform-specific release test. Availability and operating-system prompts differ by device and OS version.
Room authority and the Expo prebuilt screen
The Expo package exposes createMediaSFURoom and joinMediaSFURoom callbacks.
Their callback shape includes apiUserName and apiKey, and the pre-join flow
validates the configured credential shape before invoking them. In a released
app, supply syntactically valid placeholders, inject both callbacks, and
make both adapters ignore the callback credential values. The placeholders are
routing inputs, not authentication.
You can still use the callback types when your application has an established server-side room handoff. The adapter below accepts the callback shape but sends only the requested room payload to your backend. It never forwards callback credential arguments.
import type {
CreateRoomOnMediaSFUType,
JoinRoomOnMediaSFUType,
} from 'mediasfu-reactnative-expo';
export const createMediaSFURoom: CreateRoomOnMediaSFUType = async ({ payload }) => {
const response = await appFetch('https://api.example.test/rooms/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!response.ok) throw new Error(`Create failed: ${response.status}`);
return response.json();
};
export const joinMediaSFURoom: JoinRoomOnMediaSFUType = async ({ payload }) => {
const response = await appFetch('https://api.example.test/rooms/join', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!response.ok) throw new Error(`Join failed: ${response.status}`);
return response.json();
};
appFetch is your application's authenticated HTTP client. Your backend must
authenticate the user, enforce room and role policy, call MediaSFU with protected
authority, and return only the allowed room result. Do not add reusable
MediaSFU credentials to an Expo app, an over-the-air update, or local storage.
const clientPlaceholderCredentials = {
apiUserName: 'client00',
apiKey: '0'.repeat(64),
};
<ModernMediasfuGeneric
credentials={clientPlaceholderCredentials}
createMediaSFURoom={createMediaSFURoom}
joinMediaSFURoom={joinMediaSFURoom}
/>
If either callback is omitted, that path can fall back to the default credential-bearing request. Test create and join separately before release.
The room operations available in this package
When an approved room integration supplies the live room parameters, use these Expo package operations for the following jobs:
| What you need | Package operation | What to observe |
|---|---|---|
| Prepare a media device | createDeviceClient | A device is created from the room's RTP capabilities. |
| Start or stop microphone | clickAudio | The app shows the requested microphone state; confirm remote audio on a second device. |
| Start or stop camera | clickVideo | The app shows the requested camera state; confirm remote video on a second device. |
| Receive participant media | processConsumerTransports | A remote participant's media is rendered by your app. |
| Start or stop screen share | clickScreenShare | The operating system grants capture and another participant sees the shared content. |
| Open participant exit | launchConfirmExit | The exit confirmation is visible, then the participant leaves without ending the room for others. |
Participant updates arrive through the room's allMembers handling and are
rendered by ParticipantsModal. A participant list confirms membership state;
it does not by itself prove that remote media is playing.
The operations above receive the current room parameter object. Keep that object owned by the active room. Do not fabricate a partial parameter object merely to call a media operation: it needs the live transports, permissions, streams, and room callbacks established during connection.
Success, failure, and cleanup
- A successful create or join request returns the backend-approved room result.
Handle
401and403as an authentication or role problem,404as an unavailable room,429with bounded backoff, and5xxas a recoverable service interruption. Never replace a failed backend request with a client credential. - Treat permission approval as permission only. Confirm microphone, camera, remote playback, and screen share separately with another device.
- For participant exit, use
launchConfirmExitwith the room's active exit parameters. Stop app-owned tracks, remove app-owned subscriptions and timers, close the room screen after the exit result is handled, and clear local room snapshots.
For a headless host surface, the current Expo hook keeps end and preserve-room leave explicit:
import { Button } from 'react-native';
import { useMediasfuHeadless } from 'mediasfu-reactnative-expo';
export function HostExitButtons() {
const room = useMediasfuHeadless();
return <>
<Button title="End room" onPress={() => void room.controls.leave(false, true)} />
<Button title="Leave and keep room open" onPress={() => void room.controls.leave(false, false)} />
</>;
}
The second argument defaults to true. Await the result before closing the
screen, and use the normal authorized join flow when a host returns to a room
that was kept open.
Release checklist
- Test signed-in create and join policy against your application backend.
- Test denial, retry, and expired-session messages without exposing secrets.
- Test microphone, camera, remote audio/video, and leave with two physical devices on every supported OS.
- Test screen-share start, stop, and denial for each supported device and OS.
- Test backgrounding, reconnect, and cleanup so a later room cannot show stale participants or media state.
Build and test the Expo application after every native configuration change, then complete the checklist on physical Android and iOS devices. A JavaScript or web build cannot prove native capture, audio routing, or screen sharing.