Code Monkey home page Code Monkey logo

react-native-fingerprint-android's Introduction

react-native-fingerprint-android

Full fingerprint authentication for react native (android only).

Pictured: the example project, located at /example

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-fingerprint-android';
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) => {}):Promise<null>

Starts authentication flow, with a optional callback for warning messages, instructing your user why authentication failed.
Returns a Promise.

Resolving

Authentication was successful if this promise gets resolved.
There are no parameters.

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

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.

Installation

npm i react-native-fingerprint-android --save

Whether you're using the automatic installation method or not, don't forget to add the permission to your manifest:

android/app/src/main/AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example" android:versionCode="1" android:versionName="1.0">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
+    <uses-permission android:name="android.permission.USE_FINGERPRINT" />

Automatic installation (recommended)

Run react-native link after npm install. That should be it.

Manual installation

Same old, same old...

android/app/build.gradle

dependencies {
+   compile project(path: ':react-native-fingerprint-android')
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:23.0.1"
    compile "com.facebook.react:react-native:+"  // From node_modules
}

android/settings.gradle

include ':app'
+include ':react-native-fingerprint-android'
+project(':react-native-fingerprint-android').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fingerprint-android/android')

android/app/src/main/java/com.your.package/MainApplication.java

import java.util.Arrays;
import java.util.List;

+import io.jari.fingerprint.FingerprintPackage;
        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
-                   new MainReactPackage()
+                   new MainReactPackage(),
+                   new FingerprintPackage()
            );
        }

Todo

react-native-fingerprint-android's People

Contributors

danreynolds avatar jariz avatar matthieulemoine avatar spearmootz avatar tobycox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-fingerprint-android's Issues

Swap out FingerprintManager for FingerprintManagerCompat.

when running the plugin on a phone without fingerprint hardware, this exception is thrown at bootstrap:

Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/hardware/fingerprint/FingerprintManager;
at io.jari.fingerprint.FingerprintModule.<init>(FingerprintModule.java:33)
at io.jari.fingerprint.FingerprintPackage.createNativeModules(FingerprintPackage.java:22)
at com.facebook.react.XReactInstanceManagerImpl.processPackage(XReactInstanceManagerImpl.java:954)

i researched further and managed to figure out that this class needs to be used to determine if the phone is capable of reading fingerprints at runtime.

isCancelled should be set to true as a initial value

Thanks for your share firstly.
Before start authenticate every time, we should check the FingerPrint whether is started, if yes, cancel it. So if do cancel when FingerPrint is not started, we will get an error.
In general, the status of service should always be cleared or closed before service is started.
is it right?

java.lang.AssertionError · Tried to resolve the auth promise

Hi,

First off, thanks for putting this plugin together it really saved me a lot of time with our new ReactNative project!

I'm currently seeing a few cases where the AssertionError is being thrown due to a null Promise in the AuthenticationCallback. I haven't been able to isolate the root cause, but it appears to be somewhat timing related with a cancel() being called.

On Authentication Succeeded:

java.lang.AssertionError Tried to resolve the auth promise, but it was already resolved / rejected. This shouldn't happen. 
    FingerprintModule.java:169 io.jari.fingerprint.FingerprintModule$AuthenticationCallback.onAuthenticationSucceeded
    FingerprintManagerCompat.java:301 android.support.v4.hardware.fingerprint.FingerprintManagerCompat$Api23FingerprintManagerCompatImpl$1.onAuthenticationSucceeded
    FingerprintManagerCompatApi23.java:114 android.support.v4.hardware.fingerprint.FingerprintManagerCompatApi23$1.onAuthenticationSucceeded
    FingerprintManager.java:1165 android.hardware.fingerprint.FingerprintManager$MyHandler.sendAuthenticatedSucceeded
    FingerprintManager.java:1096 android.hardware.fingerprint.FingerprintManager$MyHandler.handleMessage
    Handler.java:102 android.os.Handler.dispatchMessage
    Looper.java:154 android.os.Looper.loop
    ActivityThread.java:6688 android.app.ActivityThread.main
    Method.java:-2 java.lang.reflect.Method.invoke
    ZygoteInit.java:1468 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
    ZygoteInit.java:1358 com.android.internal.os.ZygoteInit.main

On Authentication Error:

java.lang.AssertionError Tried to reject the auth promise, but it was already resolved / rejected. This shouldn't happen. 
    FingerprintModule.java:147 io.jari.fingerprint.FingerprintModule$AuthenticationCallback.onAuthenticationError
    FingerprintManagerCompat.java:290 android.support.v4.hardware.fingerprint.FingerprintManagerCompat$Api23FingerprintManagerCompatImpl$1.onAuthenticationError
    FingerprintManagerCompatApi23.java:104 android.support.v4.hardware.fingerprint.FingerprintManagerCompatApi23$1.onAuthenticationError
    FingerprintManager.java:1136 android.hardware.fingerprint.FingerprintManager$MyHandler.sendErrorResult
    FingerprintManager.java:1102 android.hardware.fingerprint.FingerprintManager$MyHandler.handleMessage
    Handler.java:102 android.os.Handler.dispatchMessage
    Looper.java:154 android.os.Looper.loop
    ActivityThread.java:6688 android.app.ActivityThread.main
    Method.java:-2 java.lang.reflect.Method.invoke
    ZygoteInit.java:1468 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
    ZygoteInit.java:1358 com.android.internal.os.ZygoteInit.main

I know the Android Fingerprint documentation specifically mentions that after the onAuthenticationError callback executes no other callbacks should be called, but either that isn't true 100% of the time or there may be a currency issue of some kind. Regardless, would you consider downgrading the thrown AssertionError to log a warning instead? This would prevent a full application crash in these situations and shouldn't affect the existing JavaScript API since the Promise has already been resolved/rejected.

Getting requested keys of a value that is not an object

I am trying to use react-native-fingerprint-android. I have saved with npm. However,
When I import from 'react-native-fingerprint-android', I am getting 'requested keys of a value that is not an object '.
Did I miss anything?

Auth cancelation

the design guide shows the cancel button but there is no cancel fingerprint authentication api.

is there another way to achieve this?

Change minSdkVersion to 4

when deploying my application to phone i get this gradle build error:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 23 declared in library [manager:react-native-fingerprint-android:unspecified] /Users/ant/github/pdr-manager/android/app/build/intermediates/exploded-aar/manager/react-native-fingerprint-android/unspecified/AndroidManifest.xml
  	Suggestion: use tools:overrideLibrary="io.jari.fingerprint" to force usage

simple enough, so i went ahead and added <uses-sdk tools:overrideLibrary="io.jari.fingerprint" /> to my application's AndroidManifest.xml which got the build working again.

something tells me that what i did (above) shouldn't be necessary, however. perhaps the minimum sdk version for this library should be lower?

Get the Asymmetric Keys

Can you get the Asymmetric Keys from any user's fingerprint or even just the public key ?

Looks like you can only verify a fingerprint which was beforehand stored into Android Keystore by the user. Is that correct ?

Can I get the asymmetric keys and probably save it to the server?

Fingerprint Template

Can you have access to the fingerprint template ?

I would like to be able to fetch the fingerprint template in order to create the asymmetric keys.

Not working when installed along side with mauron85/react-native-background-geolocation

Your Environment

  • Plugin version: 0.1.4
  • Platform: Android API 23, Android Simulator
  • OS version: Windows 10
  • React Native version: 0.41.2
  • mauron85/react-native-background-geolocation : 0.2.0-alpha.6

Context

When mauron85/react-native-background-geolocation is installed, fingerprint not able to work properly. But if the package is removed, it's working fine.

Debug logs when background geolocation package is installed

isHardwareDetected= false
hasPermission = true
hasEnrolledFingerprints = false

In case of error there should be return statement

In my humble opinion in example:
in code fragment:

} catch(error) {
        Toast.show(`Authentication aborted: ${error.message}`, Toast.SHORT);
    }

there should be return statement:

} catch (error) {
      console.log(error);
      Toast.show(`Authentication aborted: ${error.message}`, Toast.SHORT);
      return;
    }

Bcs when i was getting [Error: Too many attempts. Try again later.]
This code had executed: Toast.show('Auth successful!', Toast.SHORT);

warningCallback not working

Hello,

I'm trying to pass the warningCallback method to authenticate() and I get a weird native error.

Error: C++ exception in 'nativeFlushQueueImmediate'
Malformed calls from JS: field sizes are different

It works fine when I don't pass that method.
Seems like a bug

Eslint Wants an Entrypoint

While React Native picks up on the index.android.js and index.ios.js linters cannot find an index.js. Adding a blank one removes the warnings. Could we adopt a similar approach to other RN packages?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.