Unmounted Component Expo Error Crashes the App

Viewed 99

The given code shows the following error sometimes and crashes the app. Also, the firebase listener still keeps listening after unsubscribing

Well, I tried a lot of solutions... None of them worked.. Could you please help me with that?

I don't know why.. even after unsbscribing from the listener... this one still fires up on SignUp Screen :

unsubscribe = firebase.auth().onAuthStateChanged((user) => {          

            if (user) {

              firebase.firestore().collection("User Details").doc(firebase.auth().currentUser.uid).get().then((snap) => {

                try{

                if(snap.exists){

                  unsubscribe();
                  navigation.reset({
                    index : 0,
                    routes : [{ name : 'Tab'}],
                });

                }else {
                  unsubscribe();
                  navigation.reset({
                    index : 0,
                    routes : [{ name : 'User'}],
                });
                }

                }catch(e){console.log(e)}

              });

                return;


            }

            navigation.reset({
              index : 0,
              routes : [{ name : 'SignUp'}],
            });

          });

        }
      }catch(e){console.log(e)}

    }, [isReady]);

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. at node_modules\react-native\Libraries\LogBox\LogBox.js:173:8 in registerError at node_modules\react-native\Libraries\LogBox\LogBox.js:59:8 in errorImpl at node_modules\react-native\Libraries\LogBox\LogBox.js:33:4 in console.error at node_modules\expo\build\environment\react-native-logs.fx.js:27:4 in error at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:106:4 in printWarning at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:75:16 in error at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:19152:9 in warnAboutUpdateOnUnmountedFiberInDEV at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:17093:40 in scheduleUpdateOnFiber at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:11003:16 in dispatchAction at http://127.0.0.1:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false&minify=false:228649:22 in getToken$ at node_modules\regenerator-runtime\runtime.js:63:36 in tryCatch at node_modules\regenerator-runtime\runtime.js:294:29 in invoke at node_modules\regenerator-runtime\runtime.js:63:36 in tryCatch at node_modules\regenerator-runtime\runtime.js:155:27 in invoke at node_modules\regenerator-runtime\runtime.js:165:18 in PromiseImpl.resolve.then$argument_0 at node_modules\react-native\node_modules\promise\setimmediate\core.js:37:13 in tryCallOne at node_modules\react-native\node_modules\promise\setimmediate\core.js:123:24 in setImmediate$argument_0 at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:130:14 in _callTimer at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:181:14 in _callImmediatesPass at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:441:30 in callImmediates at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:387:6 in __callImmediates at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:135:6 in __guard$argument_0 at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:364:10 in __guard at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:134:4 in flushedQueue

Here's the code :

Splash screen :

try{
  if(!firebase.apps.length){

    firebase.initializeApp(firebaseConfig);

  }
}catch(err){
  console.log(err);
}

const cacheResourcesAsync = async () => {

    const images = [
      //Images

    ];
  
    const cacheImages = images.map(image => {
      return Asset.fromModule(image).downloadAsync();
    }); 

    return Promise.all(cacheImages);
}


export const SplashLoadingScreen = () => {

    const [isReady, setIsReady] = useState(false);
    const [isFire, setIsFire] = useState(false);
    const [isFont, setIsFont] = useState(false);
    const [isImages, setIsImages] = useState(false);

    const navigation = useNavigation();

    var unsubscribe;

    //Loading Fonts

    const [michromaLoaded] = useMichroma({ Michroma_400Regular });

    const [latoLoaded] = useLato({ Lato_700Bold });

    //Checking if the fonts are ready
    useEffect(() => {
      if(michromaLoaded && latoLoaded){
        setIsFont(true);
      }
    }, [michromaLoaded, latoLoaded]);

    //Checking if the Images are loaded or not
    useEffect(() => {

      cacheResourcesAsync();
      setIsImages(true);    
      
    }, []);


    //Checking if Firebase is fired up
    useEffect(() => {
      if(firebase.apps.length !== 0){

        setIsFire(true);

      }

    }, [firebase.apps.length]);

    var time;

    //Last Check before moving to other screen
    useEffect(() => {

      if(isFont && isImages && isFire){
        
        time = setTimeout(() => {
          setIsReady(true);
        }, 5000);

      }

      return () => clearTimeout(time);
  
    }, [isFont, isImages, isFire]);   

    //Moving to other screens
    useEffect(() => {

      try{

        if(isReady){

          unsubscribe = firebase.auth().onAuthStateChanged((user) => {          
            
            if (user) {

              firebase.firestore().collection("User Details").doc(firebase.auth().currentUser.uid).get().then((snap) => {
        
                try{

                if(snap.exists){
      
                  unsubscribe();
                  navigation.reset({
                    index : 0,
                    routes : [{ name : 'Tab'}],
                });
                  
                }else {
                  unsubscribe();
                  navigation.reset({
                    index : 0,
                    routes : [{ name : 'User'}],
                });
                }

                }catch(e){console.log(e)}
      
              });
                
                return;
            
              
            }
    
            navigation.reset({
              index : 0,
              routes : [{ name : 'SignUp'}],
            });
    
          });

        }
      }catch(e){console.log(e)}

    }, [isReady]);



    SplashScreen.hideAsync();

SignUp Screen :

const firebaseConfig = {
  //firebase Config
};

export const SignUpScreen = () => {

  const recaptchaVerifier = useRef(null);
  const verificationCodeTextInput = useRef(null);
  const [phoneNumber, setPhoneNumber] = useState('');
  const [verificationId, setVerificationId] = useState('');
  const [verifyError, setVerifyError] = useState();
  const [verifyInProgress, setVerifyInProgress] = useState(false);
  const [verificationCode, setVerificationCode] = useState('');
  const [confirmError, setConfirmError] = useState();
  const [confirmInProgress, setConfirmInProgress] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const isConfigValid = !!firebaseConfig.apiKey;

  const navigation = useNavigation();

  const registerForPushNotificationsAsync = async () => {

      const { status: existingStatus } = await Notifications.getPermissionsAsync();
      let finalStatus = existingStatus;
      if (existingStatus !== 'granted') {
        const { status } = await Notifications.requestPermissionsAsync();
        finalStatus = status;
      }
      if (finalStatus !== 'granted') {
        alert('Failed to get push token for push notification!');
        return;
      }
  
    if (Platform.OS === 'android') {
      Notifications.setNotificationChannelAsync('high', {
        name: 'high',
        importance: Notifications.AndroidImportance.MAX,
        vibrationPattern: [250, 250, 250, 250],
        lightColor: '#1c1c1c',
        sound : 'royal.wav'
      });
    }
    };

  registerForPushNotificationsAsync();

  const confirmation = async () => {
    const unsubscribe = firebase.auth().onAuthStateChanged((user) => {          
          
      if (user) {

        firebase.firestore().collection("User Details").doc(firebase.auth().currentUser.uid).get().then((snap) => {
  
          try{

          if(snap.exists){

            unsubscribe();
            navigation.reset({
              index : 0,
              routes : [{ name : 'Tab'}],
            });
            
          }else {
            unsubscribe();
            navigation.reset({
              index : 0,
              routes : [{ name : 'User'}],
            });
          }

          }catch(e){console.log(e)}

        });
        
      }
    });
  }
  
  const ConfirmCode = async () => {
    
      setIsLoading(true);
      setConfirmError(undefined);
      setConfirmInProgress(true);
      const credential = firebase.auth.PhoneAuthProvider.credential(
        verificationId,
        verificationCode
      );

      try{

      await firebase.auth().signInWithCredential(credential).then((user) => {}).catch(e => console.log(e));

      }catch (err) {
        setConfirmError(err);
        setConfirmInProgress(false);
      }

      setConfirmInProgress(false);
      setVerificationId('');
      setVerificationCode('');

      verificationCodeTextInput.current?.clear();

      try{
        await confirmation();
      }catch(e){console.log(e)}

  } 
0 Answers
Related