Fingerprint Authentication In Flutter

This article is about the implementation of Fingerprint Authentication in Flutter.

Introduction

 
In this article, we are talking about Fingerprint Authentication. So far, we have discussed the authentications like Google, Facebook, Phone and email/password that will need authentication at the server-side. Fingerprint Authentication is a type of local authentication with which you can include other biometric authentication also, like face and voice recognition. We are only covering Fingerprint Authentication in this article. So, tie your seat belt and let’s start :)))
 
I have found a plugin, named "local_auth" for local authentication and we are going to use it for Fingerprint Authentication.
 
 
Prerequisites
 
The fingerprint sensor in the mobile device you are testing the application on.
 

Steps

 
Step 1 
 
Create a new Flutter project. I have created a new project named “flutter_fingerprint_auth”.
 
Step 2
 
Add a dependency for the “local_auth” plugin in the “pubspec.yaml” file which is available in the project root directory.
  1. dependencies:  
  2.  flutter:  
  3.    sdk: flutter  
  4.  cupertino_icons: ^0.1.2  
  5.  local_auth: ^0.4.0+1  
NOTE
I have tried local_auth version 0.5.2+3 but it is not working; however, version 0.4.0+1 is working perfectly fine for me with Flutter packages.
 
Step 3
 
Add a permission for Android in android/app/src/main/AndroidManifest.xml.
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  2.           package="com.example.app">  
  3.   <uses-permission android:name="android.permission.USE_FINGERPRINT"/>  
  4. <manifest>  
Step 4
 
I have put some main functions for understanding the whole authentication process. Please read the comments in the code which explain you the process. I have also given my GitHub project directory link below.
  1. import 'package:flutter/material.dart';  
  2. //1. imported local authentication plugin  
  3. import 'package:local_auth/local_auth.dart';  
  4.   
  5. void main() => runApp(MyApp());  
  6.   
  7. class MyApp extends StatelessWidget {  
  8.   @override  
  9.   Widget build(BuildContext context) {  
  10.     return MaterialApp(  
  11.       theme: ThemeData(  
  12.         primarySwatch: Colors.blue,  
  13.       ),  
  14.       home: MyHomePage(title: 'Fingerprint Authentication'),  
  15.     );  
  16.   }  
  17. }  
  18.   
  19. class MyHomePage extends StatefulWidget {  
  20.   MyHomePage({Key key, this.title}) : super(key: key);  
  21.   final String title;  
  22.   
  23.   @override  
  24.   _MyHomePageState createState() => _MyHomePageState();  
  25. }  
  26.   
  27. class _MyHomePageState extends State<MyHomePage> {  
  28.   // 2. created object of localauthentication class  
  29.   final LocalAuthentication _localAuthentication = LocalAuthentication();  
  30.   // 3. variable for track whether your device support local authentication means  
  31.   //    have fingerprint or face recognization sensor or not  
  32.   bool _hasFingerPrintSupport = false;  
  33.   // 4. we will set state whether user authorized or not  
  34.   String _authorizedOrNot = "Not Authorized";  
  35.   // 5. list of avalable biometric authentication supports of your device will be saved in this array  
  36.   List<BiometricType> _availableBuimetricType = List<BiometricType>();  
  37.   
  38.   Future<void> _getBiometricsSupport() async {  
  39.     // 6. this method checks whether your device has biometric support or not  
  40.     bool hasFingerPrintSupport = false;  
  41.     try {  
  42.       hasFingerPrintSupport = await _localAuthentication.canCheckBiometrics;  
  43.     } catch (e) {  
  44.       print(e);  
  45.     }  
  46.     if (!mounted) return;  
  47.     setState(() {  
  48.       _hasFingerPrintSupport = hasFingerPrintSupport;  
  49.     });  
  50.   }  
  51.   
  52.   Future<void> _getAvailableSupport() async {  
  53.     // 7. this method fetches all the available biometric supports of the device  
  54.     List<BiometricType> availableBuimetricType = List<BiometricType>();  
  55.     try {  
  56.       availableBuimetricType =  
  57.           await _localAuthentication.getAvailableBiometrics();  
  58.     } catch (e) {  
  59.       print(e);  
  60.     }  
  61.     if (!mounted) return;  
  62.     setState(() {  
  63.       _availableBuimetricType = availableBuimetricType;  
  64.     });  
  65.   }  
  66.   
  67.   Future<void> _authenticateMe() async {  
  68.     // 8. this method opens a dialog for fingerprint authentication.  
  69.     //    we do not need to create a dialog nut it popsup from device natively.  
  70.     bool authenticated = false;  
  71.     try {  
  72.       authenticated = await _localAuthentication.authenticateWithBiometrics(  
  73.         localizedReason: "Authenticate for Testing"// message for dialog  
  74.         useErrorDialogs: true,// show error in dialog  
  75.         stickyAuth: true,// native process  
  76.       );  
  77.     } catch (e) {  
  78.       print(e);  
  79.     }  
  80.     if (!mounted) return;  
  81.     setState(() {  
  82.       _authorizedOrNot = authenticated ? "Authorized" : "Not Authorized";  
  83.     });  
  84.   }  
  85.   
  86.   @override  
  87.   void initState() {  
  88.     _getBiometricsSupport();  
  89.     _getAvailableSupport();  
  90.     super.initState();  
  91.   }  
  92.   
  93.   @override  
  94.   Widget build(BuildContext context) {  
  95.     return Scaffold(  
  96.       appBar: AppBar(  
  97.         title: Text(widget.title),  
  98.       ),  
  99.       body: Center(  
  100.         child: Column(  
  101.           mainAxisAlignment: MainAxisAlignment.center,  
  102.           children: <Widget>[  
  103.             Text("Has FingerPrint Support : $_hasFingerPrintSupport"),  
  104.             Text(  
  105.                 "List of Biometrics Support: ${_availableBuimetricType.toString()}"),  
  106.             Text("Authorized : $_authorizedOrNot"),  
  107.             RaisedButton(  
  108.               child: Text("Authorize Now"),  
  109.               color: Colors.green,  
  110.               onPressed: _authenticateMe,  
  111.             ),  
  112.           ],  
  113.         ),  
  114.       ),  
  115.     );  
  116.   }  
  117. }  
Sometimes, there may arrive some error as stated below.
 
Error - import androidx.annotation.NonNull;
 
Solution
 
Put android.useAndroidX=true and android.enableJetifier=true in the android/gradle.properties file.
 
 

Conclusion

 
Thus, we learned how to use Fingerprint Authentication in an Android device using local_auth plugin in Flutter. This article was all about fingerprint authentication in Android; you can also use this for iOS but for that, you need to add permission to iOS which is defined in the plugin's documentation. You can use this authentication when you need a very high level of security like making payments or confidential transactions.