Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native. How to get user local authentication whenever the app comes from the background?

Well, I can`t find anything like this on the web, so I am hoping someone can help me on this one.

I`m creating a bare react native android app, and I need to check for the user's Local Authentication whenever the app comes from the background.

I'm using Expo Authentication to handle the authentication, however, checking the app state with AppState from React Native is not useful, since every time the authentication screen (biometrics, facial recognition or even the PIN number) shows up on the screen the AppState will change from active to background, so it will require for an authentication again and again, because it will always come from the 'background'.

I'm not able to control it with a variable, since I don't have any identifier that could tell me the app came from expo Local Authentication screen, so I`m stuck on this "which came first, the chicken or the egg" problem.

Here is the part of the component that I`ve created to handle it so far:

    AppState.addEventListener('change', _handleAppStateChange);

    return () => {
      AppState.removeEventListener('change', _handleAppStateChange);
    };
  }, []);

  const _handleAppStateChange = async (nextAppState: any) => {
    if (
      appState.current.match(/inactive|background/) &&
      nextAppState === 'active'
    ) {
      clearTimeout(authenticationRequiredTimeout);
      if (user && shouldAuthenticate) {
        LocalAuthentication.hasHardwareAsync().then((hasHardware) => {
          if (hasHardware) {
            LocalAuthentication.isEnrolledAsync().then((isEnrolled) => {
              if (isEnrolled) {
                LocalAuthentication.authenticateAsync().then(
                  (authentication) => {
                    if (authentication.success !== true) {
                      logout();
                    }
                    setShouldAuthenticate(false);
                    console.log(authentication);
                  },
                );
              }
            });
          }
        });
      }
    } else {
      let timeout = setTimeout(() => {
        setShouldAuthenticate(true);
      }, 5000);
      setAuthenticationRequiredTimeout(timeout);
    }
    console.log(shouldAuthenticate);
    appState.current = nextAppState;
    console.log('AppState', appState);
  };```

Any help would be much appreciatted
like image 962
Victor Tavares Avatar asked Nov 03 '25 02:11

Victor Tavares


1 Answers

I've ran into the same problem and solved it as follows:

My app contains a store (just a single instance of a class). In this store I have added a property temporarilyMovedToBackground. Whenever I call Expo's localAuthentication, I first set the property temporarilyMovedToBackground to true. After the call finishes I set it to false again, with a timeout of 1000. Then, when checking if the appState changed to background, I also check if temporarilyMovedToBackground is false.

like image 122
Thijs Avatar answered Nov 04 '25 19:11

Thijs