React Native Fingerprint Scanner is a React Native library for authenticating users with Fingerprint (TouchID).
The usage of the TouchID is based on a framework, named Local Authentication.
It provides a Default View that prompts the user to place a finger to the iPhone’s button for scanning.
Using an expandable Android Fingerprint API library, which combines Samsung and MeiZu's official Fingerprint API.
Samsung and MeiZu's Fingerprint SDK supports most devices which system versions less than Android 6.0.
$ npm install react-native-fingerprint-scanner --save
$ react-native link react-native-fingerprint-scanner
- In XCode, in the project navigator, right click
Libraries
âžśAdd Files to [your project's name]
- Go to
node_modules
âžśreact-native-fingerprint-scanner
and addReactNativeFingerprintScanner.xcodeproj
- In XCode, in the project navigator, select your project. Add
libReactNativeFingerprintScanner.a
to your project'sBuild Phases
âžśLink Binary With Libraries
- Run your project (
Cmd+R
)
- Open up
android/app/src/main/java/[...]/MainActivity.java
- Add
import com.hieuvp.fingerprint.ReactNativeFingerprintScannerPackage;
to the imports at the top of the file - Add
new ReactNativeFingerprintScannerPackage()
to the list returned by thegetPackages()
method
- Append the following lines to
android/settings.gradle
:include ':react-native-fingerprint-scanner' project(':react-native-fingerprint-scanner').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fingerprint-scanner/android')
- Insert the following lines inside the dependencies block in
android/app/build.gradle
:compile project(':react-native-fingerprint-scanner')
Add the following permissions to their respective files:
In your AndroidManifest.xml
:
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
In your Info.plist
:
<key>NSFaceIDUsageDescription</key>
<string>$(PRODUCT_NAME) requires FaceID access to allows you quick and secure access.</string>
-
Make sure the following versions are all correct in
android/app/build.gradle
android { compileSdkVersion 25 buildToolsVersion "25.0.3" ... defaultConfig { targetSdkVersion 25
-
Add necessary rules to
android/app/proguard-rules.pro
# MeiZu Fingerprint -keep class com.fingerprints.service.** { *; } -dontwarn com.fingerprints.service.** # Samsung Fingerprint -keep class com.samsung.android.sdk.** { *; } -dontwarn com.samsung.android.sdk.**
iOS Implementation
import React, { Component, PropTypes } from 'react';
import { AlertIOS } from 'react-native';
import FingerprintScanner from 'react-native-fingerprint-scanner';
class FingerprintPopup extends Component {
componentDidMount() {
FingerprintScanner
.authenticate({ description: 'Scan your fingerprint on the device scanner to continue' })
.then(() => {
this.props.handlePopupDismissed();
AlertIOS.alert('Authenticated successfully');
})
.catch((error) => {
this.props.handlePopupDismissed();
AlertIOS.alert(error.message);
});
}
render() {
return false;
}
}
FingerprintPopup.propTypes = {
handlePopupDismissed: PropTypes.func.isRequired,
};
export default FingerprintPopup;
Android Implementation
import React, { Component, PropTypes } from 'react';
import {
Alert,
Image,
Text,
TouchableOpacity,
View,
ViewPropTypes
} from 'react-native';
import FingerprintScanner from 'react-native-fingerprint-scanner';
import ShakingText from './ShakingText.component';
import styles from './FingerprintPopup.component.styles';
class FingerprintPopup extends Component {
constructor(props) {
super(props);
this.state = { errorMessage: undefined };
}
componentDidMount() {
FingerprintScanner
.authenticate({ onAttempt: this.handleAuthenticationAttempted })
.then(() => {
this.props.handlePopupDismissed();
Alert.alert('Fingerprint Authentication', 'Authenticated successfully');
})
.catch((error) => {
this.setState({ errorMessage: error.message });
this.description.shake();
});
}
componentWillUnmount() {
FingerprintScanner.release();
}
handleAuthenticationAttempted = (error) => {
this.setState({ errorMessage: error.message });
this.description.shake();
};
render() {
const { errorMessage } = this.state;
const { style, handlePopupDismissed } = this.props;
return (
<View style={styles.container}>
<View style={[styles.contentContainer, style]}>
<Image
style={styles.logo}
source={require('./assets/finger_print.png')}
/>
<Text style={styles.heading}>
Fingerprint{'\n'}Authentication
</Text>
<ShakingText
ref={(instance) => { this.description = instance; }}
style={styles.description(!!errorMessage)}>
{errorMessage || 'Scan your fingerprint on the\ndevice scanner to continue'}
</ShakingText>
<TouchableOpacity
style={styles.buttonContainer}
onPress={handlePopupDismissed}
>
<Text style={styles.buttonText}>
BACK TO MAIN
</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
FingerprintPopup.propTypes = {
style: ViewPropTypes.style,
handlePopupDismissed: PropTypes.func.isRequired,
};
export default FingerprintPopup;
Checks if Fingerprint Scanner is able to be used by now.
- Returns a
Promise<string>
biometryType: String
- The type of biometric authentication supported by the device.error: FingerprintScannerError { name, message }
- The reason of failure.
componentDidMount() {
FingerprintScanner
.isSensorAvailable()
.then(biometryType => this.setState({ biometryType }))
.catch(error => this.setState({ errorMessage: error.message }));
}
Starts Fingerprint authentication on iOS.
- Returns a
Promise
description: String
- the string to explain the request for user authentication.fallbackEnabled: Boolean
- default totrue
, whether to display fallback button (e.g. Enter Password).
componentDidMount() {
FingerprintScanner
.authenticate({ description: 'Scan your fingerprint on the device scanner to continue' })
.then(() => {
this.props.handlePopupDismissed();
AlertIOS.alert('Authenticated successfully');
})
.catch((error) => {
this.props.handlePopupDismissed();
AlertIOS.alert(error.message);
});
}
Starts Fingerprint authentication on Android.
- Returns a
Promise
onAttempt: Function
- a callback function when users are trying to scan their fingerprint but failed.
componentDidMount() {
FingerprintScanner
.authenticate({ onAttempt: this.handleAuthenticationAttempted })
.then(() => {
this.props.handlePopupDismissed();
Alert.alert('Fingerprint Authentication', 'Authenticated successfully');
})
.catch((error) => {
this.setState({ errorMessage: error.message });
this.description.shake();
});
}
Stops fingerprint scanner listener and optimizes memory.
- Returns a
Void
componentWillUnmount() {
FingerprintScanner.release();
}
Value | OS |
---|---|
Touch ID | iOS |
Face ID | iOS |
Fingerprint | Android |
Name | Message |
---|---|
AuthenticationNotMatch | No match |
AuthenticationFailed | Authentication was not successful because the user failed to provide valid credentials |
UserCancel | Authentication was canceled by the user - e.g. the user tapped Cancel in the dialog |
UserFallback | Authentication was canceled because the user tapped the fallback button (Enter Password) |
SystemCancel | Authentication was canceled by system - e.g. if another application came to foreground while the authentication dialog was up |
PasscodeNotSet | Authentication could not start because the passcode is not set on the device |
FingerprintScannerNotAvailable | Authentication could not start because Fingerprint Scanner is not available on the device |
FingerprintScannerNotEnrolled | Authentication could not start because Fingerprint Scanner has no enrolled fingers |
FingerprintScannerUnknownError | Could not authenticate for an unknown reason |
FingerprintScannerNotSupported | Device does not support Fingerprint Scanner |
DeviceLocked | Authentication was not successful, the device currently in a lockout of 30 seconds |
MIT