Candidates never join the same room

/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable no-undef */
import React, {useEffect, useRef, useState} from 'react';
import {View,Text,SafeAreaView,StyleSheet,LogBox,TouchableOpacity} from 'react-native'
import {NavigationContainer, StackActions} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

import AuthNavigator from './src/assets/navigations/AuthNavigator';
import OnboardingScreen from './src/screens/Onboarding/Onboarding';
import CallEnd from './src/components/CallEnd';
import CallAnswer from './src/components/CallAnswer';
import IconContainer from './src/components/IconContainer';
import CameraSwitch from './src/components/CameraSwitch';
import VideoOff from './src/components/VideoOff';
import VideoOn from './src/components/VideoOn';
import SocketIOClient from 'socket.io-client';
import InCallManager from 'react-native-incall-manager';
import RNRestart from 'react-native-restart';

import {
  mediaDevices,
  RTCPeerConnection,
  RTCView,
  RTCIceCandidate,
  RTCSessionDescription,
} from 'react-native-webrtc';
import MicOn from './src/components/MicOn';
import MicOff from './src/components/MicOff';
import { HOST } from './src/api/api';
import AsyncStorage from '@react-native-async-storage/async-storage';


LogBox.ignoreAllLogs();

function App() {
  const [auth, setAuth] = useState(false);
  const [localStream, setlocalStream] = useState(null);
  const [localCandidate, setLocalCandidate] = useState([]);
  const [remoteStream, setRemoteStream] = useState(null);
  const [localMicOn, setlocalMicOn] = useState(true);
  const [localWebcamOn, setlocalWebcamOn] = useState(true);
  const [type, setType] = useState('JOIN');
  const[userId,setUserId]=useState(null);
  const[callerName,setCallerName]=useState(null);
  const[calleeName,setCalleeName]=useState(null);
  let remoteRTCMessage = useRef(null);
  let isFront = false;
  const [callerId,setCallerId] = useState(
   "caller"
  );
  const otherUserId = useRef(null);


const setOtherUserId=(data)=>{
  otherUserId.current=data.userId;
  setCalleeName(data.name)
}


  const socket = SocketIOClient(HOST.websocket, {
    transports: ['websocket'],
    query: {
      callerId,
    },
  });


  const peerConnection = useRef(
    new RTCPeerConnection({
      configuration: {
    offerToReceiveAudio: true,
    offerToReceiveVideo: true
  },
      iceServers: [
        {
          urls: 'stun:stun.l.google.com:19302',
        },
        { url: 'stun:stun1.l.google.com:19302' },
        { url: 'stun:stun2.l.google.com:19302' },
        { url: 'stun:stun3.l.google.com:19302' },
      ],
    }),
  );


  useEffect(() => {

    socket.on('newCall', data => {
     
      if(userId&&data.calleeId==userId)
      {
        
      remoteRTCMessage.current = data.rtcMessage;
      otherUserId.current = data.callerId;
      setCallerName(data.callerName);
      setType('INCOMING_CALL');
    }
    });

    socket.on('newEnd', data => {
     
      if(userId&&(data.user1==userId||data.user2==userId))
      {
        peerConnection.current.close();
        //setType('JOIN');
        RNRestart.Restart();
    }
    });

    socket.on('callAnswered', async data => {
    
      if(userId&&(data.callerId==userId) )
      {
        remoteRTCMessage.current =data.rtcMessage ;
        let message= new RTCSessionDescription(remoteRTCMessage.current);
        console.log(message);
        //peerConnection.current.remoteDescription=message;
       await peerConnection.current.setRemoteDescription(message); 
      
       
   
      console.log(peerConnection);
      setType('WEBRTC_ROOM');
      }
      if(userId&&(data.calleeId==userId) )
      {
        console.log("Buraya Bak");
        await localCandidate.forEach((candidate, index) => {
         
           peerConnection.current
          .addIceCandidate(
            new RTCIceCandidate({
              candidate: candidate.candidate,
              sdpMid: candidate.id,
              sdpMLineIndex: candidate.label,
            }),
          )
          .then(data => {
            console.log('SUCCESS');
          })
          .catch(err => {
            console.log('Error', err);
          });

       });

        setType('WEBRTC_ROOM');
      }
    });

    socket.on('ICEcandidateRoom', async data => {
      if(userId&&(data.callerId==userId||data.calleeId==userId))
      {
      let message = data.rtcMessage;
      if(data.callerId==userId && data.type=="answer")
      {
      if (peerConnection.current) {
        await peerConnection.current
          .addIceCandidate(
            new RTCIceCandidate({
              candidate: message.candidate,
              sdpMid: message.id,
              sdpMLineIndex: message.label,
            }),
          )
          .then(data => {
            console.log('SUCCESS');
          })
          .catch(err => {
            console.log('Error', err);
          });



      }
      }

      if(data.calleeId==userId && data.type=="offer")
      {
       
        localCandidate.push(message);
      
    }

    }

    });
    mediaDevices.enumerateDevices().then(sourceInfos => {
      let videoSourceId;
      for (let i = 0; i < sourceInfos.length; i++) {
        const sourceInfo = sourceInfos[i];
        if (
          sourceInfo.kind == 'videoinput' &&
          sourceInfo.facing == (isFront ? 'user' : 'environment')
        ) {
          videoSourceId = sourceInfo.deviceId;
        }
      }

      mediaDevices
        .getUserMedia({
          audio: true,
          video: {
            mandatory: {
              minWidth: 500, // Provide your own width, height and frame rate here
              minHeight: 300,
              minFrameRate: 30,
            },
            facingMode: isFront ? 'user' : 'environment',
            optional: videoSourceId ? [{sourceId: videoSourceId}] : [],
          },
        })
        .then(stream => {
          // Got stream!

          setlocalStream(stream);

          // setup stream listening
          peerConnection.current.addStream(stream);
        })
        .catch(error => {
          // Log error
        });
    });

    peerConnection.current.onaddstream = event => {
      setRemoteStream(event.stream);
    };

    return () => {
      socket.off('newCall');
      socket.off('callAnswered');
      socket.off('ICEcandidate');
    };
  }
  , [userId,otherUserId]);

  useEffect(() => {
    
    InCallManager.start();
    InCallManager.setKeepScreenOn(true);
    InCallManager.setForceSpeakerphoneOn(true);

    return () => {
      InCallManager.stop();
    };
  
  }, []);

  
  function sendICEcandidate(data) {
    socket.emit('ICEcandidate', data);
  }

  async function callUser() {

    const offerOptions = {
      offerToReceiveAudio: true,
      offerToReceiveVideo: true
  };
    const sessionDescription = await peerConnection.current.createOffer(offerOptions);
    await peerConnection.current.setLocalDescription(sessionDescription);

     sendCall({
      userId:userId,
      calleeId: otherUserId.current,
      rtcMessage: sessionDescription,
    });

    peerConnection.current.addEventListener('icecandidate', event => {
     
      if (event.candidate) {
      
        sendICEcandidate({
         callerId: userId,
         userId: userId,
         calleeId: otherUserId.current,
         type:"offer",
         rtcMessage: {
           label: event.candidate.sdpMLineIndex,
           id: event.candidate.sdpMid,
           candidate: event.candidate.candidate,
         },
       });
     }
     
    });

  }

  async function callEnd(userId,otherUserId) {
   
    sendEnd({
      user1:userId,
      user2: otherUserId,
    });
    setType('JOIN');


  }

  async function callSave(userId) {
    sendSave({
      userId:userId,
      calleeId: null,
      rtcMessage: null,
    });
   
  }
  async function processAccept(otherUserId) {

    const offerOptions = {
      offerToReceiveAudio: true,
      offerToReceiveVideo: true
  };

    peerConnection.current.setRemoteDescription(
      new RTCSessionDescription(remoteRTCMessage.current),
    );
    const sessionDescription = await peerConnection.current.createAnswer(offerOptions);
    await peerConnection.current.setLocalDescription(sessionDescription);

   

    answerCall({
      userId:userId,
      callerId: otherUserId.current,
      rtcMessage: sessionDescription,
    });

    peerConnection.current.addEventListener('icecandidate', event => {
     
      if (event.candidate) {
        sendICEcandidate({
          callerId: otherUserId.current,
          userId: userId,
          calleeId: userId,
          type:"answer",
          rtcMessage: {
            label: event.candidate.sdpMLineIndex,
            id: event.candidate.sdpMid,
            candidate: event.candidate.candidate,
          },
        });
     }
     
    });
   

  }

  function answerCall(data) {
    socket.emit('answerCall', data);
  }

  function sendCall(data) {
    socket.emit('call', data);
    setType('OUTGOING_CALL');
  }

  function sendEnd(data) {
    socket.emit('end', data);
  }

  function sendSave(data) {
    socket.emit('save', data);
  }
 
  const OutgoingCallScreen = () => {
    return (
      <View
        style={{
          flex: 1,
          justifyContent: 'space-around',
          backgroundColor: '#050A0E',
        }}>
        <View
          style={{
            padding: 35,
            justifyContent: 'center',
            alignItems: 'center',
            borderRadius: 14,
          }}>
          <Text
            style={{
              fontSize: 16,
              color: '#D0D4DD',
            }}>
            Calling ...
          </Text>

          <Text
            style={{
              fontSize: 36,
              marginTop: 12,
              color: '#ffff',
              letterSpacing: 6,
            }}>
            {calleeName} 
          </Text>
        </View>
        <View
          style={{
            justifyContent: 'center',
            alignItems: 'center',
          }}>
          <TouchableOpacity
            onPress={() => {
             callEnd(userId,otherUserId.current);
            }}
            style={{
              backgroundColor: '#FF5D5D',
              borderRadius: 30,
              height: 60,
              aspectRatio: 1,
              justifyContent: 'center',
              alignItems: 'center',
            }}>
            <CallEnd width={50} height={12} />
          </TouchableOpacity>
        </View>
      </View>
    );
  };

  const IncomingCallScreen = () => {
    return (
      <View
        style={{
          flex: 1,
          justifyContent: 'space-around',
          backgroundColor: '#050A0E',
        }}>
        <View
          style={{
            padding: 35,
            justifyContent: 'center',
            alignItems: 'center',
            borderRadius: 14,
          }}>
          <Text
            style={{
              fontSize: 36,
              marginTop: 12,
              color: '#ffff',
            }}>
            {callerName} 
          </Text>
          <Text
            style={{
              fontSize: 16,
              color: '#D0D4DD',
            }}>
           is Calling..
          </Text>
        </View>
        <View
          style={{
            flexDirection:'row',
            justifyContent: 'center',
            alignItems: 'center',
          }}>
          <TouchableOpacity
            onPress={() => {
              processAccept(otherUserId);
             setType('WEBRTC_ROOM');
            }}
            style={{
              backgroundColor: 'green',
              borderRadius: 30,
              height: 60,
              aspectRatio: 1,
              justifyContent: 'center',
              alignItems: 'center',
            }}>
            <CallAnswer height={28} fill={'#fff'} />
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => {
              callEnd(userId,otherUserId.current);
            }}
            style={{
              backgroundColor: '#FF5D5D',
              borderRadius: 30,
              height: 60,
              aspectRatio: 1,
              justifyContent: 'center',
              alignItems: 'center',
              marginLeft:30,
            }}>
            <CallEnd width={50} height={12} />
          </TouchableOpacity>
        </View>
      </View>
    );
  };

  function switchCamera() {
    localStream.getVideoTracks().forEach(track => {
      track._switchCamera();
    });
  }

  function toggleCamera() {
    localWebcamOn ? setlocalWebcamOn(false) : setlocalWebcamOn(true);
    localStream.getVideoTracks().forEach(track => {
      localWebcamOn ? (track.enabled = false) : (track.enabled = true);
    });
  }

  function toggleMic() {
    localMicOn ? setlocalMicOn(false) : setlocalMicOn(true);
    localStream.getAudioTracks().forEach(track => {
      localMicOn ? (track.enabled = false) : (track.enabled = true);
    });
  }

  function leave () {
    peerConnection.current.close();
    setlocalStream(null);
    //RNRestart.Restart();
    setType('JOIN');
  }

  const WebrtcRoomScreen = () => {
    return (
      <View
        style={{
          flex: 1,
          backgroundColor: '#050A0E',
          paddingHorizontal: 12,
          paddingVertical: 12,
        }}>
        {localStream ? (
          <RTCView
            objectFit={'cover'}
            style={{flex: 1, backgroundColor: '#050A0E'}}
            streamURL={localStream.toURL()}
          />
        ) : null}
        {remoteStream ? (
          <RTCView
            objectFit={'cover'}
            style={{
              flex: 1,
              backgroundColor: '#050A0E',
              marginTop: 8,
            }}
            streamURL={remoteStream.toURL()}
          />
        ) : null}
        <View
          style={{
            marginVertical: 12,
            flexDirection: 'row',
            justifyContent: 'space-evenly',
          }}>
          <IconContainer
            backgroundColor={'red'}
            onPress={() => {
              leave();
            }}
            Icon={() => {
              return <CallEnd height={26} width={26} fill="#FFF" />;
            }}
          />
          <IconContainer
            style={{
              borderWidth: 1.5,
              borderColor: '#2B3034',
            }}
            backgroundColor={!localMicOn ? '#fff' : 'transparent'}
            onPress={() => {
              toggleMic();
            }}
            Icon={() => {
              return localMicOn ? (
                <MicOn height={24} width={24} fill="#FFF" />
              ) : (
                <MicOff height={28} width={28} fill="#1D2939" />
              );
            }}
          />
          <IconContainer
            style={{
              borderWidth: 1.5,
              borderColor: '#2B3034',
            }}
            backgroundColor={!localWebcamOn ? '#fff' : 'transparent'}
            onPress={() => {
              toggleCamera();
            }}
            Icon={() => {
              return localWebcamOn ? (
                <VideoOn height={24} width={24} fill="#FFF" />
              ) : (
                <VideoOff height={36} width={36} fill="#1D2939" />
              );
            }}
          />
          <IconContainer
            style={{
              borderWidth: 1.5,
              borderColor: '#2B3034',
            }}
            backgroundColor={'transparent'}
            onPress={() => {
              switchCamera();
            }}
            Icon={() => {
              return <CameraSwitch height={24} width={24} fill="#FFF" />;
            }}
          />
        </View>
      </View>
    );
  };



  switch (type) {
    case 'JOIN':
      return (
        <SafeAreaView style={styles.safeArea}>
          {auth ? (
            <View style={styles.conteiner}>
              <OnboardingScreen callUser={callUser} setOtherUserId={setOtherUserId} callSave={callSave} callUserId={setUserId} />
            </View>
          ) : (
            <NavigationContainer>
              <AuthNavigator callUser={callUser} setOtherUserId={setOtherUserId} callSave={callSave} callUserId={setUserId}/>
            </NavigationContainer>
          )}
        </SafeAreaView>
      );
    case 'INCOMING_CALL':
      return IncomingCallScreen();
    case 'OUTGOING_CALL':
      return OutgoingCallScreen();
    case 'WEBRTC_ROOM':
      return WebrtcRoomScreen();
    default:
      return (
        <SafeAreaView style={styles.safeArea}>
          {auth ? (
            <View style={styles.conteiner}>
              <OnboardingScreen    callUser={callUser} setOtherUserId={setOtherUserId} callSave={callSave} callUserId={setUserId}/>
            </View>
          ) : (
            <NavigationContainer>
              <AuthNavigator  callUser={callUser} setOtherUserId={setOtherUserId} callSave={callSave} callUserId={setUserId}/>
            </NavigationContainer>
          )}
        </SafeAreaView>
      );
  }



}

export default App;
const styles = StyleSheet.create({
  conteiner: {flex: 1, justifyContent: 'center', alignItems: 'center'},
  safeArea: {
    flex: 1,
  },
});

Candidates created but never join the same room ? What is the problem. “react-native”: “0.71.6”, “react-native-webrtc”: “^111.0.3”,