Here is my App.tsx file. I am receiving stream content from a web app and using WebRTC with React Native. While everything seems to be working fine, I’m facing an issue where peerConnection.ontrack is not triggering. None of the console logs are showing up, and I’m not receiving any stream data to display the stream.
How can I resolve this issue? I also have some related questions, but those pertain to a web app rather than React Native.
// App.tsx
import React, {useState} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {firebaseConfig} from './firebaseConfig';
import OfferCodeScreen from './OfferCodeScreen';
import app from '@react-native-firebase/app';
import database from '@react-native-firebase/database';
import {
RTCPeerConnection,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStream,
} from 'react-native-webrtc';
import RTCTrackEvent from 'react-native-webrtc/lib/typescript/RTCTrackEvent';
// Initialize Firebase if not already
if (app.apps.length === 0) {
app.initializeApp(firebaseConfig);
}
// STUN / TURN config
const rtcConfig: RTCConfiguration = {
iceServers: [{urls: 'stun:stun.l.google:19302'}],
};
const App = () => {
const [remoteStream, setRemoteStream] = useState<MediaStream | null>(null);
const [connected, setConnected] = useState(false);
const connectWithOfferCode = async (offerCode: string) => {
try {
// 1. Get the offer from Firebase
const offerSnapshot = await database()
.ref(`offers/${offerCode}`)
.once('value');
const offerData = offerSnapshot.val();
if (!offerData) {
console.error('No offer found for this code.');
return;
}
// 2. Create a new PeerConnection
const peerConnection = new RTCPeerConnection(rtcConfig);
// 3. Set remote description with the web's offer
await peerConnection.setRemoteDescription(
new RTCSessionDescription(offerData),
);
// 4. Create answer and set local description
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
// 5. Post the answer to Firebase
await database().ref(`answers/${offerCode}`).set({
type: answer.type,
sdp: answer.sdp,
});
// 6. Listen for the web’s ICE candidates
database()
.ref(`candidates/${offerCode}/webToMobile`)
.on('child_added', async snapshot => {
const candidateData = snapshot.val();
if (candidateData) {
const candidate = new RTCIceCandidate(candidateData);
await peerConnection.addIceCandidate(candidate);
}
});
// 7. Send our ICE candidates to the web
peerConnection.onicecandidate = (event: any) => {
if (event.candidate) {
console.log('onicecandidate', event.candidate);
database()
.ref(`candidates/${offerCode}/mobileToWeb`)
.push(event.candidate.toJSON());
}
};
// 8. On track, set the remote stream
peerConnection.ontrack = (event: any) => {
console.log('coming here');
const [stream] = event.streams;
console.log('Stream Data: ', stream);
setRemoteStream(stream);
setConnected(true);
console.log('connected: ', connected);
};
console.log('Connected with offer code:', offerCode);
} catch (err) {
console.error('Error connecting:', err);
}
};
return (
<View style={styles.container}>
{!connected ? (
<>
<Text style={styles.title}>Enter Offer Code to Connect</Text>
<OfferCodeScreen onConnect={connectWithOfferCode} />
</>
) : (
<>
<Text style={styles.title}>
Connected! Displaying Screen Share...
</Text>
{remoteStream && (
<RTCView streamURL={remoteStream.toURL()} style={styles.video} />
)}
</>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {flex: 1, backgroundColor: '#fff', paddingTop: 40},
title: {fontSize: 18, textAlign: 'center', marginBottom: 20},
video: {flex: 1, backgroundColor: 'black'},
});
export default App;
Here is my App.tsx file. I am receiving stream content from a web app and using WebRTC with React Native. While everything seems to be working fine, I’m facing an issue where peerConnection.ontrack is not triggering. None of the console logs are showing up, and I’m not receiving any stream data to display the stream.
How can I resolve this issue? I also have some related questions, but those pertain to a web app rather than React Native.
// App.tsx
import React, {useState} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {firebaseConfig} from './firebaseConfig';
import OfferCodeScreen from './OfferCodeScreen';
import app from '@react-native-firebase/app';
import database from '@react-native-firebase/database';
import {
RTCPeerConnection,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStream,
} from 'react-native-webrtc';
import RTCTrackEvent from 'react-native-webrtc/lib/typescript/RTCTrackEvent';
// Initialize Firebase if not already
if (app.apps.length === 0) {
app.initializeApp(firebaseConfig);
}
// STUN / TURN config
const rtcConfig: RTCConfiguration = {
iceServers: [{urls: 'stun:stun.l.google.com:19302'}],
};
const App = () => {
const [remoteStream, setRemoteStream] = useState<MediaStream | null>(null);
const [connected, setConnected] = useState(false);
const connectWithOfferCode = async (offerCode: string) => {
try {
// 1. Get the offer from Firebase
const offerSnapshot = await database()
.ref(`offers/${offerCode}`)
.once('value');
const offerData = offerSnapshot.val();
if (!offerData) {
console.error('No offer found for this code.');
return;
}
// 2. Create a new PeerConnection
const peerConnection = new RTCPeerConnection(rtcConfig);
// 3. Set remote description with the web's offer
await peerConnection.setRemoteDescription(
new RTCSessionDescription(offerData),
);
// 4. Create answer and set local description
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
// 5. Post the answer to Firebase
await database().ref(`answers/${offerCode}`).set({
type: answer.type,
sdp: answer.sdp,
});
// 6. Listen for the web’s ICE candidates
database()
.ref(`candidates/${offerCode}/webToMobile`)
.on('child_added', async snapshot => {
const candidateData = snapshot.val();
if (candidateData) {
const candidate = new RTCIceCandidate(candidateData);
await peerConnection.addIceCandidate(candidate);
}
});
// 7. Send our ICE candidates to the web
peerConnection.onicecandidate = (event: any) => {
if (event.candidate) {
console.log('onicecandidate', event.candidate);
database()
.ref(`candidates/${offerCode}/mobileToWeb`)
.push(event.candidate.toJSON());
}
};
// 8. On track, set the remote stream
peerConnection.ontrack = (event: any) => {
console.log('coming here');
const [stream] = event.streams;
console.log('Stream Data: ', stream);
setRemoteStream(stream);
setConnected(true);
console.log('connected: ', connected);
};
console.log('Connected with offer code:', offerCode);
} catch (err) {
console.error('Error connecting:', err);
}
};
return (
<View style={styles.container}>
{!connected ? (
<>
<Text style={styles.title}>Enter Offer Code to Connect</Text>
<OfferCodeScreen onConnect={connectWithOfferCode} />
</>
) : (
<>
<Text style={styles.title}>
Connected! Displaying Screen Share...
</Text>
{remoteStream && (
<RTCView streamURL={remoteStream.toURL()} style={styles.video} />
)}
</>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {flex: 1, backgroundColor: '#fff', paddingTop: 40},
title: {fontSize: 18, textAlign: 'center', marginBottom: 20},
video: {flex: 1, backgroundColor: 'black'},
});
export default App;
Share
Improve this question
edited Jan 25 at 16:15
halfer
20.4k19 gold badges108 silver badges201 bronze badges
asked Jan 20 at 6:07
dheeraj kumardheeraj kumar
233 bronze badges
1 Answer
Reset to default 0I attempted to resolve the issue but couldn't find a solution, so I decided to use the new Expo DOM components. These components allow me to write React.js code directly within a React Native file. The 'use dom' directive then converts the files into a native WebView proxy component.
For a deeper understanding and detailed guidance, you can refer to the official Expo blog post and documentation:
https://expo.dev/blog/the-magic-of-expo-dom-components https://docs.expo.dev/guides/dom-components/