Error Showing Memory Leak While Signing Up


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. How should I solve this error?? The error occurs while using these screens… I guess it’s caused by .onAuthStateChanged listener but not sure… Because I still have a doubt on .AuthStateChanged Listener’s implementation as even while I am on Signup screen, after authentication, the firebase.onAuthStateChanged Listener of Splash Screen also gets executed somehow even when I have unsubscribed from it… So, can someone please help?

Splash Screen Code :

 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();

Sign Up Screen Code :

 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: [0, 250, 250, 250],
        lightColor: '#1c1c1c',
      });
    }
    };

  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)}

  }

User Details Screen Code

export const UserDetails = () => {

    const [name, setName] = useState("");
    const [age, setAge] = useState(0);
    const [email, setEmail] = useState("");
    const [token, setToken] = useState('');

    const navigation = useNavigation();

    useEffect(() => {
        getToken();
    }, []);

    const getToken = async () => {
        
        let token = (await Notifications.getExpoPushTokenAsync()).data;
        setToken(token);
        
    }

    const move = () => {
        if(name.length < 2){
            Alert.alert("Please enter a valid name");
        } else{
            if(age < 5){
                Alert.alert("Please enter a age greater than 5 years");
            } else if (email.length < 10 || !email.includes("@") || !email.includes(".")){
                Alert.alert("Please enter an appropritate Email Address");
            }else {
                firebase.firestore().collection("User Details").doc(firebase.auth().currentUser.uid).set({"name" : name, "age" : age, "phone" : (firebase.auth().currentUser.phoneNumber).slice(3),
                    "update" : 3, "total" : 0, "completed" : 0, "cancelled" : 0, "in progress" : 0, "email" : email, "notify" : token});
                navigation.navigate('Tab');

                firebase.auth().currentUser.updateEmail(email).then(() => {}).catch((error) => {console.log(error)});
            
                firebase.auth().currentUser.sendEmailVerification();
            }
        }
        
    }

Source: JavaSript – Stack Overflow

November 22, 2021
Category : News
Tags: expo | javascript | memory-leaks | react native

Leave a Reply

Your email address will not be published. Required fields are marked *

Sitemap | Terms | Privacy | Cookies | Advertising

Senior Software Developer

Creator of @LzoMedia I am a backend software developer based in London who likes beautiful code and has an adherence to standards & love's open-source.