Face Id Authentication for android in React-Native

2.7k Views Asked by At

i want android face_id authentication sdk for my react native android app login. I have used plugins which are available which support only finger authentication and password for android. Please let me know if there is any plugin or sdk available so that i can use in react native android.

How can i use this code in react native by creating native module. https://developer.android.com/training/sign-in/biometric-auth

private Executor executor;
private BiometricPrompt biometricPrompt;
private BiometricPrompt.PromptInfo promptInfo;

executor = ContextCompat.getMainExecutor(this);
biometricPrompt = new BiometricPrompt(MainActivity.this,
        executor, new BiometricPrompt.AuthenticationCallback() {
    @Override
    public void onAuthenticationError(int errorCode,
            @NonNull CharSequence errString) {
        super.onAuthenticationError(errorCode, errString);
        Toast.makeText(getApplicationContext(),
            "Authentication error: " + errString, Toast.LENGTH_SHORT)
            .show();
    }

    @Override
    public void onAuthenticationSucceeded(
            @NonNull BiometricPrompt.AuthenticationResult result) {
        super.onAuthenticationSucceeded(result);
        Toast.makeText(getApplicationContext(),
            "Authentication succeeded!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onAuthenticationFailed() {
        super.onAuthenticationFailed();
        Toast.makeText(getApplicationContext(), "Authentication failed",
            Toast.LENGTH_SHORT)
            .show();
    }
});

promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setNegativeButtonText("Use account password")
        .build();
3

There are 3 best solutions below

2
On

Here is one of many api's that you do it react-native-fingerprint-scanner and an example below:

const isBiometricValid = async () =>
  FingerprintScanner.authenticate({
    description: 'Scan your fingerprint on the device scanner to continue'
  });

const availableBiometric = async () => FingerprintScanner.isSensorAvailable();

const secureLogin = async ({
  cpf,
  password,
  setFieldError,
  storedUser,
  navigation,
  dispatch,
  setUseManualPassword,
  useManualPassword,
  setFieldValue
}) => {
  const authArgs = {
    cpf,
    password,
    setFieldError,
    navigation,
    dispatch
  };

  try {
    const availableBiometricType = await availableBiometric();

    if (!availableBiometricType) {
      return AuthCreators.getToken({ ...authArgs });
    }

    if (useManualPassword) {
      return AuthCreators.getToken({
        ...authArgs,
        cpf: storedUser[0]
      });
    }

    if (storedUser) {
      const userAccessGranted = await isBiometricValid();

      if (userAccessGranted) {
        const storedPasswordEncrypted = await AsyncStorage.getItem('@__:password');
        const decryptedPasswordBytes = CryptoJS.AES.decrypt(
          storedPasswordEncrypted,
          Config.USER_PASSWORD_ENCRYPTION_KEY
        );
        const decryptedPassword = decryptedPasswordBytes.toString(CryptoJS.enc.Utf8);

        return AuthCreators.getToken({
          ...authArgs,
          cpf: storedUser[0],
          password: decryptedPassword
        });
      }
    }

    return AuthCreators.getToken({
      ...authArgs,
      biometric: normalizedBiometricType(availableBiometricType)
    });
  } catch (error) {
    return biometricAuthFailure({
      ...authArgs,
      error,
      setUseManualPassword,
      setFieldValue,
      storedUser
    });
  }
};

You can test and debug by open a device like iOS 11 (or anyone with faceID as default) for example and enroll biometric at Features > FaceID > Enrolled.

0
On

Commonly in Android is used fingerprint and iOS Face ID for most recent devices, I consider that not is possible to manage a similar way that Face ID in Android.

For example, this library specific that Face-ID and Touch-ID only available for iOS devices and Biometrics is to Android, works a similar way that Touch-ID.

Other users answered a similar question.

1
On

From my recent research it seems that expo-local-authentication works with face recognition, but only if android device has fingerprint authentication hardware also.

Expo-local-authentication function supportedAuthenticationTypesAsync() returns always only information about AuthenticationType.FINGERPRINT even if facial recognition is also available on android device. Despite that it works properly even if device with fingerprint hardware doesn't have fingerprint data and has only face data. Then expo-local-authentication use face unlock.

Problem happens when android device doesn't have fingerprint hardware, but have face recognition availability. Then supportedAuthenticationTypesAsync() returns only undefined and authenticateAsync() doesn't work.

Here is snack created for testing: https://snack.expo.dev/-Y34x2K7- But you will need a device with such hardware.

I prepared precise question here to find solution for case with android devices with face recognition unlock but without fingerprint unlock here: Face Id, biometry, face recognition unlock on Android devices in React Native