Introduction
Nowadays almost all smartphone comes with either Fingerprint Sensor or Face ID or both. We being a developer can make use of this feature and secure our app. So in this tutorial, I will explain to you about how to code and add a fingerprint authentication method in the Flutter app.
These days most apps are building their own fingerprint authentication with the like of WhatsApp and PayPal. Just like me, you might have used third-party apps to lock your app. This would mean you have extra security just for a particular app.
So without further delay, let us jump in the coding portion and have exciting feature in our own app.
Creating New Flutter Project
As usual we will start by creating new flutter project. I will be naming the project as “InstaTouchAuth“.
flutter create InstaTouchAuth
Importing Plugin and Configuration
Flutter is a great framework to work with and one of the reason is its abundant plugin. So for this project, we will be using one such plugin called “local_auth“.
To add this plugin, open pubsec.yaml file and add the line as shown below:
dependencies: local_auth: ^0.6.3+4
After adding the plugin, you can run “flutter pub get”.
Now we have imported the plugin but we will need to make some changes in root files of Android and iOS to make it work. Alternatively, you can also refer plugin page for instruction.
Configuration for Android Integration
Firstly let us check what configuration we need to make for android device.
We will need to add the permission in AndroidManifest.xml file for fingerprint:
<manifest xmlns:android="<http://schemas.android.com/apk/res/android>"
package="com.example.InstaTouchAuth">
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<manifest>
As per the instruction given in the plugin page, the local_auth uses FragmentActivity as opposed to Activity. I was stuck here for quite some time but could ultimately get through.
To make changes you need to edit the MainActivity file of android. It would depend if you are using Java or Kotlin. The file is located at:
<project>/android/app/src/main/kotlin/com/example/InstaTouchAuth/MainActivity.kt
You can add following code to this file:
package com.example.InstaTouchAuth
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine( flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
Configuration for iOS Integration
The local_auth supports both TouchID and FaceID. If you want to include the FaceID you will need to add the following lines to Info.plist file.
<key>NSFaceIDUsageDescription</key> <string>Why is my app authenticating using face id?</string>
Writing the Fingerprint Authentication Codes
Great we have made everything ready now. Now we can start to do some dart code. Here also we will start by modifying the main.dart file.
import 'package:InstaTouchAuth/TouchID.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: TouchID(),
);
}
}
This main file might be familiar and we do not have any special thing here. We will use all the logic in a new file and call it TouchID.dart file.
Let us now see the code for our new file.
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';
import 'package:flutter/services.dart';
class TouchID extends StatefulWidget {
@override
_TouchIDState createState() => _TouchIDState();
}
class _TouchIDState extends State<TouchID> {
final LocalAuthentication localAuth = LocalAuthentication();
String _authorizeText = 'Not Authorized!';
Future<void> _authorize() async {
bool _isAuthorized = false;
try {
_isAuthorized = await localAuth.authenticateWithBiometrics(
localizedReason: 'Please authenticate to Complete this process',
useErrorDialogs: true,
stickyAuth: true,
);
} on PlatformException catch (e) {
print(e);
}
if (!mounted) return;
setState(() {
if (_isAuthorized) {
_authorizeText = "Authorized Successfully!";
} else {
_authorizeText = "Not Authorized!";
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('InstaTouchAuth'),
centerTitle: true,
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
_authorizeText,
style: TextStyle(color: Colors.black38, fontSize: 20),
),
),
RaisedButton(
child: Text(
'Authorize',
style: TextStyle(color: Colors.white, fontSize: 20),
),
color: Colors.red,
onPressed: _authorize,
)
],
)),
);
}
}
We start by importing the necessary module. Then we implement the fingerprint authentication method.
Firstly we initialize the LocalAuthentication. Then we have a Future function where we will perform the actual authentication. You can see the function below:
_isAuthorized = await localAuth.authenticateWithBiometrics(
localizedReason: 'Please authenticate to Complete this process',
useErrorDialogs: true,
stickyAuth: true,
);
} on PlatformException catch (e) {
print(e);
On Android, you can check only for the existence of fingerprint hardware prior to API 29 (Android Q). Therefore, if you would like to support other biometrics types (such as face scanning) and you want to support SDKs lower than Q, do not call getAvailableBiometrics. Simply call authenticateWithBiometrics. This will return an error if there was no hardware available.
You can set the stickyAuth option on the plugin to true so that plugin does not return failure if the app is put to the background by the system. This might happen if the user receives a phone call before they get a chance to authenticate. With stickyAuth set to false, this would result in plugin returning failure result to the Dart app. If set to true, the plugin will retry authenticating when the app resumes.
Here I would like you to note that if you want to get the list of biometrics option available, then you can implement like code below:
List<BiometricType> availableBiometrics =
await auth.getAvailableBiometrics();
if (Platform.isIOS) {
if (availableBiometrics.contains(BiometricType.face)) {
// Face ID.
} else if (availableBiometrics.contains(BiometricType.fingerprint)) {
// Touch ID.
}
}
That is all, you can go and run the app.
Output
If all goes well then you will see the output as shown in image below.
Conclusion
That is all folks!
We have successfully implemented fingerprint authentication with Flutter and local_auth plugin. Not only the biometric but we have also seen how to implement FaceID authentication.
I have uploaded the code in Github for your reference. I have used UPLOADING YOUR FLUTTER PROJECT TO GITHUB tutorial for this purpose.