I have create a next js 13 app to share the camera feed with webrtc and firestore. This is my page.tsx. i cant make this serve side becaus i have use react hooks and i cant move this to client side because it contains firestore and server data.
"use client";
import { useEffect, useRef, useState } from "react";
import { firestore } from "@/services/_configs/firestore";
export default function Page({ params }: { params: { userid: string } }) {
const servers = {
iceServers: [
{
urls: ['stun:stun1.l.google.com:19302',
'stun:stun2.l.google.com:19302']
}
],
iceCandidatePoolSize: 10,
}
const pc = new RTCPeerConnection(servers);
const [viewerId, setViewerId] = useState('');
const [localStream, setLocalStream] = useState<MediaStream | null>(null);
const [remoteStream, setRemoteStream] = useState<MediaStream | null>(null);
const localVideo = useRef<HTMLVideoElement | null>(null);
const remoteVideo = useRef<HTMLVideoElement | null>(null);
useEffect(() => {
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then((currentStream) => {
setLocalStream(currentStream);
});
setRemoteStream(new MediaStream());
localStream?.getTracks().forEach((track) => {
pc.addTrack(track, localStream);
})
pc.ontrack = event => {
event.streams[0].getTracks().forEach((track) => {
remoteStream?.addTrack(track);
});
}
if (localVideo.current != null && remoteVideo.current != null) {
localVideo.current.srcObject = localStream;
remoteVideo.current.srcObject = remoteStream;
}
}, []);
const requestLiveStream = async () => {
const callDoc = firestore.collection('calls').doc();
const offerCandidate = callDoc.collection('offerCandidates');
const answerCandidate = callDoc.collection('answerCandidates');
setViewerId(callDoc.id);
pc.onicecandidate = event => {
event.candidate && offerCandidate.add(event.candidate.toJSON());
}
const offerDescription = await pc.createOffer();
await pc.setLocalDescription(offerDescription);
const offer = {
sdp: offerDescription.sdp,
type: offerDescription.type,
}
await callDoc.set({ offer });
callDoc.onSnapshot((snapshot) => {
const data = snapshot.data();
if (!pc.currentLocalDescription && data?.answer) {
const answerDescription = new RTCSessionDescription(data.answer);
pc.setRemoteDescription(answerDescription);
}
})
answerCandidate.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === "added") {
const candidate = new RTCIceCandidate(change.doc.data());
pc.addIceCandidate(candidate);
}
})
});
}
const startLiveStream = async () => {
const callId = viewerId;
const callDoc = firestore.collection('calls').doc(callId);
const offerCandidate = callDoc.collection('offerCandidates');
const answerCandidate = callDoc.collection('answerCandidates');
pc.onicecandidate = event => {
event.candidate && answerCandidate.add(event.candidate.toJSON());
}
const callData = (await callDoc.get()).data();
const offerDescription = callData?.offer;
await pc.setRemoteDescription(new RTCSessionDescription(offerDescription));
const answerDescription = await pc.createAnswer();
await pc.setLocalDescription(answerDescription);
const answer = {
sdp: answerDescription.sdp,
type: answerDescription.type,
}
await callDoc.update({ answer });
offerCandidate.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
console.log(change);
if (change.type === "added") {
let data = change.doc.data();
pc.addIceCandidate(new RTCIceCandidate(data));
}
})
});
}
return (
<div>
<h1>{viewerId}</h1>
<input
type="text"
value={viewerId}
onChange={(e) => setViewerId(e.target.value)}
/>
<button onClick={requestLiveStream}>view live</button>
<button onClick={startLiveStream}>Answer live</button>
<video playsInline ref={remoteVideo} autoPlay />
<br />
<video playsInline ref={localVideo} autoPlay />
</div>
);
}
i get this error how do i solve that.
Module not found: Can't resolve 'net'
https://nextjs.org/docs/messages/module-not-found
Import trace for requested module:
./node_modules/request/request.js
./node_modules/request/index.js
./node_modules/retry-request/index.js
./node_modules/google-gax/build/src/streamingCalls/streaming.js
./node_modules/google-gax/build/src/fallback.js
./node_modules/@google-cloud/firestore/build/src/index.js
./src/services/_configs/firestore.ts
./src/app/app/live/page.tsx
I try to separate the firestore code to another but i could not do that because i have that firestore data change events in client side.