oblador / react-native-keychain

:key: Keychain Access for React Native
MIT License
3.21k stars 520 forks source link

No support for Face ID on Android #697

Closed paulwaweru-onmo closed 2 days ago

paulwaweru-onmo commented 2 days ago

Hi, I noticed the getSupportedBiometryType function returns {"biometryType": null} for Android devices that support facial recognition. I'm using the Samsung Z Flip and I've setup biometrics with Face ID only, and I'm using the following logic:

static async checkBiometricSupport() {
    try {
      const biometryType = await Keychain.getSupportedBiometryType();

      const result = await Keychain.canImplyAuthentication({
        authenticationType: Keychain.AUTHENTICATION_TYPE.BIOMETRICS,
      });

      console.log({ biometryType, result });

      if (!biometryType) {
        throw new Error('Biometrics not supported on this device');
      }

      return {
        available: true,
        biometryType,
        biometryTypeString: BiometricAuth.getBiometryTypeString(biometryType),
      };
    } catch (error) {
      return {
        available: false,
        error: error.message,
      };
    }
  }

biometryType is null and result is false. I've also specified the following in my Android manifest:

<uses-permission android:name="android.permission.USE_BIOMETRIC" />

Is there something I'm missing?

DorianMazur commented 2 days ago

Hey @paulwaweru-onmo,

FACE auth on most Android devices is not considered strong biometrics, which is why the library does not return it. For more details, you can refer to the Android Developer Documentation on BiometricManager.Authenticators.

  fun isStrongBiometricAuthAvailable(context: Context): Boolean {
    return BiometricManager.from(context)
        .canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) ==
        BiometricManager.BIOMETRIC_SUCCESS
  }
  fun getSupportedBiometryType(promise: Promise) {
    try {
      var reply: String? = null
      if (!DeviceAvailability.isStrongBiometricAuthAvailable(reactApplicationContext)) {
        reply = null
      } else {
        if (isFingerprintAuthAvailable) {
          reply = FINGERPRINT_SUPPORTED_NAME
        } else if (isFaceAuthAvailable) {
          reply = FACE_SUPPORTED_NAME
        } else if (isIrisAuthAvailable) {
          reply = IRIS_SUPPORTED_NAME
        }
      }
      promise.resolve(reply)
    } 
    // [...]
  }

Mre info -> https://eu.community.samsung.com/t5/galaxy-z-fold-z-flip/why-is-facial-recognition-so-poor-on-android/td-p/10624302

paulwaweru-onmo commented 2 days ago

ahh, thank you so much for the quick response @DorianMazur! Learned a bit from this. Happy to close the issue in that case :)