README
react-native-android-legacy-fingerprint
Legacy fingerprint authentication for react native (Android only). Based on the deprecated FingerprintManger
API. You probably want expo-local-authentication or react-native-fingerprint-scanner
Based heavily on react-native-fingerprint-android, but updated with:
- AndroidX support library use
- More FingerprintManager message codes
- Written with TypeScript & Kotlin
- Respects project settings for
targetSdk
& build.gradle config
Why?
The currently-maintained fingerprint/biometric auth libraries for React Native have all adopted the new BiometricPrompt
. This is great!
However, some vendors (*cough* Samsung) have custom biometics overlays that lead to confusing UX on affected devices. In this case, it may be desirable to use the older FingerprintManger
API.
Status: pre-release
- Android:
- Requires Kotlin
- iOS:
- No support planned
- react-native:
- supported versions ">= 0.60.0"
Installation
with react-native ">=0.60.0"0. Setup Kotlin
1. Install latest version from npm
Demo
|
Example
This is a simplified version. There are a few more concerns you should be aware of. see 'Watch out!'
For the full version, see the example
directory.
import Fingerprint from 'react-native-android-legacy-fingerprint';
import { ToastAndroid as Toast } from 'react-native';
(async() => {
const hardware = await Fingerprint.isHardwareDetected();
const permission = await Fingerprint.hasPermission();
const enrolled = await Fingerprint.hasEnrolledFingerprints();
if (!hardware || !permission || !enrolled) {
let message = !enrolled ? 'No fingerprints registered.' : !hardware ? 'This device doesn\'t support fingerprint scanning.' : 'App has no permission.'
Toast.show(message, Toast.SHORT);
return;
}
try {
await Fingerprint.authenticate(warning => {
Toast.show(`Try again: ${warning.message}`, Toast.SHORT);
});
} catch(error) {
Toast.show(`Authentication aborted: ${error.message}`, Toast.SHORT);
}
Toast.show("Auth successful!", Toast.SHORT);
})();
API
All functions & constants are static.
.authenticate(warningCallback?: (response: FingerprintError) => void):Promise<boolean>
Starts authentication flow, with a optional callback for warning messages, instructing your user why authentication failed.
Returns a Promise.
Resolving
Authentication resolves to a boolean indicating if the fingerprint was recognized and auth succeeded.
If the result is false
, the fingerprint was recognized but not valid.
Rejection
Authentication has failed if the promise gets rejected.
Callback will receive a single parameter with the following structure: (example)
{
"code": 1,
"message": "The hardware is unavailable. Try again later."
}
This code will be match one of the following constants in the FingerprintAndroid module:
Constant | Description |
---|---|
FingerprintAndroid.FINGERPRINT_ERROR_CANCELED | The operation was canceled because the fingerprint sensor is unavailable. |
FingerprintAndroid.FINGERPRINT_ERROR_HW_UNAVAILABLE | The hardware is unavailable. |
FingerprintAndroid.FINGERPRINT_ERROR_LOCKOUT | The operation was canceled because the API is locked out due to too many attempts. |
FingerprintAndroid.FINGERPRINT_ERROR_NO_SPACE | Error state returned for operations like enrollment; the operation cannot be completed because there's not enough storage remaining to complete the operation. |
FingerprintAndroid.FINGERPRINT_ERROR_TIMEOUT | Error state returned when the current request has been running too long. |
FingerprintAndroid.FINGERPRINT_ERROR_UNABLE_TO_PROCESS | Error state returned when the sensor was unable to process the current image. |
For more info on the constants, see Android FingerprintManager docs
warningCallback
warningCallback is the only and optional parameter to .authenticate()
.
If present, warningCallback gets called with a single parameter, a object with the following structure:
{
"code": 1,
"message": "Only acquired a partial fingerprint. Try again."
}
This code will be match one of the following constants in FingerprintAndroid:
Constant | Description |
---|---|
FingerprintAndroid.FINGERPRINT_ACQUIRED_IMAGER_DIRTY | The fingerprint image was too noisy due to suspected or detected dirt on the sensor. |
FingerprintAndroid.FINGERPRINT_ACQUIRED_INSUFFICIENT | The fingerprint image was too noisy to process due to a detected condition |
FingerprintAndroid.FINGERPRINT_ACQUIRED_PARTIAL | Only a partial fingerprint image was detected. |
FingerprintAndroid.FINGERPRINT_ACQUIRED_TOO_FAST | The fingerprint image was incomplete due to quick motion. |
FingerprintAndroid.FINGERPRINT_ACQUIRED_TOO_SLOW | The fingerprint image was unreadable due to lack of motion. |
FingerprintAndroid.FINGERPRINT_ACQUIRED_AUTH_FAILED | Custom constant added by react-native-fingerprint-android, to simplify API. This code is used when a fingerprint was recognized but not valid. |
For more info on the constants, see Android FingerprintManager docs
.isAuthenticationCanceled(): Promise<boolean>
Tells you whether or not authentication is running or not.
.hasPermission(): Promise<boolean>
Will check if android.permission.USE_FINGERPRINT
is granted to this app. (should always return true if you add the permission to your AndroidManifest...)
hasEnrolledFingerprints(): Promise<boolean>
Determine if there is at least one fingerprint enrolled.
isHardwareDetected(): Promise<boolean>
Determine if fingerprint hardware is present and functional.
cancelAuthentication(): Promise<void>
Manually cancel the authentication, this is required to follow the design principles in the design guidelines. When called this will trigger a rejection of the original authenticate promise.
Watch out!
React Native Fingerprint Android is mostly just a set of bindings to Android FingerprintManager.
Alas, it's very low level. You are still responsible for:
- Making sure the device has fingerprints enrolled by calling
FingerprintAndroid.hasEnrolledFingerprints()
(if you don't check this before starting authentication, any valid fingerprint will be accepted) - Making sure your app has proper permissions setup (see installation guide below)
- Making sure device has supported hardware by calling
FingerprintAndroid.isHardwareDetected()
- Making sure you display the correct icon, as defined by the design guidelines.
- Restarting authentication if screen turns off. (see example project for on an example on how to do that)
If you don't do any of the checks before calling FingerprintAndroid.authenticate
, it will either directly fail, or your app will contain security vulnerabilities.