0
0
Fluttermobile~20 mins

Biometric authentication in Flutter - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Biometric Login Screen
This screen allows users to log in using their fingerprint or face recognition if available on their device.
Target UI
-------------------------
|  Biometric Login      |
|-----------------------|
|                       |
|   [Fingerprint Icon]   |
|                       |
|  Tap to authenticate  |
|                       |
|  [Login with PIN]      |
-------------------------
Show a fingerprint icon centered on the screen
Display a message 'Tap to authenticate' below the icon
When user taps the fingerprint icon, start biometric authentication
If authentication succeeds, show a success message
If authentication fails or is not available, show an error message
Provide a button 'Login with PIN' below to fallback to PIN login
Starter Code
Flutter
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';

class BiometricLoginScreen extends StatefulWidget {
  @override
  _BiometricLoginScreenState createState() => _BiometricLoginScreenState();
}

class _BiometricLoginScreenState extends State<BiometricLoginScreen> {
  final LocalAuthentication auth = LocalAuthentication();
  String _message = 'Tap to authenticate';

  // TODO: Add method to handle biometric authentication

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Biometric Login')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(Icons.fingerprint, size: 100, color: Colors.blue),
            SizedBox(height: 20),
            Text(_message, style: TextStyle(fontSize: 18)),
            SizedBox(height: 40),
            ElevatedButton(
              onPressed: () {
                // TODO: Add PIN login navigation
              },
              child: Text('Login with PIN'),
            ),
          ],
        ),
      ),
    );
  }
}
Task 1
Task 2
Task 3
Task 4
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';

class BiometricLoginScreen extends StatefulWidget {
  @override
  _BiometricLoginScreenState createState() => _BiometricLoginScreenState();
}

class _BiometricLoginScreenState extends State<BiometricLoginScreen> {
  final LocalAuthentication auth = LocalAuthentication();
  String _message = 'Tap to authenticate';

  Future<void> _authenticate() async {
    bool authenticated = false;
    try {
      authenticated = await auth.authenticate(
        localizedReason: 'Please authenticate to login',
        options: const AuthenticationOptions(
          biometricOnly: true,
          stickyAuth: true,
        ),
      );
    } catch (e) {
      setState(() {
        _message = 'Error: ${e.toString()}';
      });
      return;
    }

    setState(() {
      _message = authenticated ? 'Authentication successful!' : 'Authentication failed. Try again.';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Biometric Login')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            GestureDetector(
              onTap: _authenticate,
              child: const Icon(Icons.fingerprint, size: 100, color: Colors.blue),
            ),
            const SizedBox(height: 20),
            Text(_message, style: const TextStyle(fontSize: 18)),
            const SizedBox(height: 40),
            ElevatedButton(
              onPressed: () {
                // Placeholder for PIN login navigation
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('Navigate to PIN login screen')),
                );
              },
              child: const Text('Login with PIN'),
            ),
          ],
        ),
      ),
    );
  }
}

We use the local_auth package to access biometric features.

The _authenticate method tries to authenticate the user with biometrics only.

If authentication succeeds, we update the message to show success.

If it fails or an error occurs, we show an error message.

The fingerprint icon is wrapped in a GestureDetector so tapping it starts authentication.

The 'Login with PIN' button currently shows a message as a placeholder for navigation.

Final Result
Completed Screen
-------------------------
|  Biometric Login      |
|-----------------------|
|                       |
|   [Fingerprint Icon]   |
|                       |
| Authentication success |
|                       |
|  [Login with PIN]      |
-------------------------
User taps fingerprint icon to start biometric authentication
If successful, message changes to 'Authentication successful!'
If failed, message changes to 'Authentication failed. Try again.'
Tapping 'Login with PIN' shows a temporary message about navigation
Stretch Goal
Add a fallback to device passcode authentication if biometrics are not available or fail
💡 Hint
Use the 'authenticate' method without 'biometricOnly: true' option to allow device passcode fallback