How To Create a OTP Authentication App Using Flutter



In this project, we're excited to present our "Otp authentication" app, developed using Flutter. Our project will guide you through the creation of this engaging Otp authentication app using Flutter. You'll learn how to build an intuitive and responsive user interface. Let's start...


Source Code for the main.dart file




Add the following Code inside your main.dart file :



                
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'home_page.dart';


void main() async{
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp();
    runApp(const MyApp());
}

class MyApp extends StatelessWidget {
    const MyApp({super.key});

    @override
    Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Home(),
    );
    }
}

                    
                    
  
            

            


Source Code for the home_page.dart file




Add the following Code inside your home_page.dart file :



                
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'done.dart';
import 'numeric_pad.dart';



class Home extends StatefulWidget {
    const Home({super.key});

    @override
    State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home>
{
    TextEditingController _codecontroller = new TextEditingController();
    String phoneNumber = "", data = "";
    final FirebaseAuth _auth = FirebaseAuth.instance;
    String smscode = "";

    _signInWithMobileNumber() async {
    try {
        await _auth.verifyPhoneNumber(
            phoneNumber: '+91' + data.trim(),
            verificationCompleted: (PhoneAuthCredential authCredential) async {
            await _auth.signInWithCredential(authCredential).then((value) {
                Navigator.push(
                    context, MaterialPageRoute(builder: (context) => Done()));
            });
            },
            verificationFailed: ((error)
            {
            print(error);
            }),
            codeSent: (String verificationId, [int? forceResendingToken]) {
            showDialog(
                context: context,
                barrierDismissible: false,
                builder: (context) => AlertDialog(
                    title: Text("Enter OTP"),
                    content: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                        TextField(
                        controller: _codecontroller,
                        )
                    ],
                    ),
                    actions: [
                    ElevatedButton(
                        onPressed: () {
                            FirebaseAuth auth = FirebaseAuth.instance;
                            smscode = _codecontroller.text;
                            PhoneAuthCredential _credential =
                            PhoneAuthProvider.credential(
                                verificationId: verificationId,
                                smsCode: smscode);
                            auth.signInWithCredential(_credential)
                                .then((result) {
                            if (result != null) {
                                Navigator.pop(context);
                                Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                        builder: (context) => Done()));
                            }
                            }).catchError((e) {
                            showDialog(
                                context: context,
                                builder: (BuildContext context) {
                                return AlertDialog(
                                    title: Text('Error Occured'),
                                    content: Text('Please check and enter the correct verification code'), // Format total price with two decimal places
                                    actions: [
                                    TextButton(
                                        onPressed: () {
                                        Navigator.of(context).pop();
                                        },
                                        child: Text('Close'),
                                    ),
                                    ],
                                );
                                },
                            );
                            // print(e);
                            });
                        },
                        child: Text("Done"))
                    ],
                ));
            },
            codeAutoRetrievalTimeout: (String verificationId) {
            verificationId = verificationId;
            },
            timeout: Duration(seconds: 45));
    } catch (e) {
        print(e);
    }
    }

    @override
    Widget build(BuildContext context) {
    return
        Scaffold(
        resizeToAvoidBottomInset: false,
        appBar: AppBar(
        title: Text(
            "Continue with phone",
            style: TextStyle(
            fontSize: 18,
            fontWeight: FontWeight.bold,
            color: Colors.black,
            ),
        ),
        backgroundColor: Colors.white,
        elevation: 0,
        centerTitle: true,
        ),
        body: SafeArea(
        child: Column(
            children: [
            Expanded(
                child: Container(
                decoration: BoxDecoration(
                    gradient: LinearGradient(
                    begin: Alignment.topCenter,
                    end: Alignment.bottomCenter,
                    colors: [
                        Color(0xFFFFFFFF),
                        Color(0xFFF7F7F7),
                    ],
                    ),
                ),
                child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                    SizedBox(

                        height: 150,
                        child: Image.asset('images/holding-phone.png'),
                    ),
                    Padding(
                        padding:
                        EdgeInsets.symmetric(vertical: 14, horizontal: 64),
                        child: Text(
                        "You'll receive a 6 digit code to verify next.",
                        style: TextStyle(
                            fontSize: 20,
                            color: Color(0xFF818181),
                        ),
                        ),
                    ),
                    ],
                ),
                ),
            ),
            Container(
                height: MediaQuery.of(context).size.height * 0.13,
                decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.all(
                    Radius.circular(25),
                ),
                ),
                child: Padding(
                padding: EdgeInsets.all(16),
                child: Row(
                    children: [
                    Container(
                        width: 230,
                        child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                            Text(
                            "Enter your phone",
                            style: TextStyle(
                                fontSize: 14,
                                fontWeight: FontWeight.bold,
                                color: Colors.grey,
                            ),
                            ),
                            SizedBox(
                            height: 8,
                            ),
                            Text(
                            phoneNumber,
                            style: TextStyle(
                                fontSize: 24,
                                fontWeight: FontWeight.bold,
                            ),
                            ),
                        ],
                        ),
                    ),
                    Expanded(
                        child: GestureDetector(
                        onTap: () {
                            data = phoneNumber;
                            phoneNumber = "";

                            setState(() {

                            });

                            _signInWithMobileNumber();
                        },
                        child: Container(
                            decoration: BoxDecoration(
                            color: Color(0xFFFFDC3D),
                            borderRadius: BorderRadius.all(
                                Radius.circular(15),
                            ),
                            ),
                            child: Center(
                            child: Text(
                                "Continue",
                                style: TextStyle(
                                fontSize: 18,
                                fontWeight: FontWeight.bold,
                                ),
                            ),
                            ),
                        ),
                        ),
                    ),
                    ],
                ),
                ),
            ),
            NumericPad(
                onNumberSelected: (value) {
                setState(() {
                    if (value != -1) {
                    phoneNumber = phoneNumber + value.toString();
                    }
                    else
                    {
                    phoneNumber =
                        phoneNumber.substring(0, phoneNumber.length - 1);
                    }
                });
                },
            ),
            ],
        ),
        ),
    );
    }
}
                    

            

            


Source Code for the numeric_pad.dart file




Add the following Code inside your numeric_pad.dart file :



                
import 'package:flutter/material.dart';

class NumericPad extends StatelessWidget {
    final Function(int) onNumberSelected;

    NumericPad({required this.onNumberSelected});

    @override
    Widget build(BuildContext context) {
    return Container(
        color: Color(0xFFF5F4F9),
        child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
            Container(
            height: MediaQuery.of(context).size.height * 0.10,
            child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                buildNumber(1),
                buildNumber(2),
                buildNumber(3),
                ],
            ),
            ),
            Container(
            height: MediaQuery.of(context).size.height * 0.10,
            child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                buildNumber(4),
                buildNumber(5),
                buildNumber(6),
                ],
            ),
            ),
            Container(
            height: MediaQuery.of(context).size.height * 0.10,
            child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                buildNumber(7),
                buildNumber(8),
                buildNumber(9),
                ],
            ),
            ),
            Container(
            height: MediaQuery.of(context).size.height * 0.10,
            child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                buildEmptySpace(),
                buildNumber(0),
                buildBackspace(),
                ],
            ),
            ),
        ],
        ),
    );
    }

    Widget buildNumber(int number) {
    return Expanded(
        child: GestureDetector(
        onTap: () {
            onNumberSelected(number);
        },
        child: Padding(
            padding: EdgeInsets.all(10),
            child: Container(
            decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.all(
                Radius.circular(15),
                ),
            ),
            child: Center(
                child: Text(
                number.toString(),
                style: TextStyle(
                    fontSize: 28,
                    fontWeight: FontWeight.bold,
                    color: Color(0xFF1F1F1F),
                ),
                ),
            ),
            ),
        ),
        ),
    );
    }

    Widget buildBackspace() {
    return Expanded(
        child: GestureDetector(
        onTap: () {
            onNumberSelected(-1);
        },
        child: Padding(
            padding: EdgeInsets.all(10),
            child: Container(
            decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.all(
                Radius.circular(15),
                ),
            ),
            child: Center(
                child: Icon(
                Icons.backspace,
                size: 28,
                color: Color(0xFF1F1F1F),
                ),
            ),
            ),
        ),
        ),
    );
    }

    Widget buildEmptySpace() {
    return Expanded(
        child: Container(),
    );
    }
}
                    

            

            


Source Code for the done.dart file




Add the following Code inside your done.dart file :



                
import 'package:flutter/material.dart';

class Done extends StatefulWidget {
    const Done({super.key});

    @override
    State<Done> createState() => _DoneState();
}

class _DoneState extends State<Done> {
    @override
    Widget build(BuildContext context) {
    return
        Scaffold(

        backgroundColor: Colors.white,
        appBar: AppBar(
        automaticallyImplyLeading: false,
            backgroundColor: Colors.white,
        elevation: 0,),
        body: Center(
        child: SingleChildScrollView(
            scrollDirection: Axis.vertical,
            child: Column(

            children: [

                Container(
                child: Image.asset('images/verify.webp',
                height: 300,),

                ),
                SizedBox(
                height: 40,
                ),
                Text('Phone Number Verified',
                style: TextStyle(
                fontSize: 30,
                fontWeight: FontWeight.bold,
                color: Colors.green
                ),)
            ],
            ),
        ),
        ),
    );
    }
}
                    

            

            


The Output is shown below :






Contact Us

REACH US

SERVICES

  • CODING
  • ON-LINE PREPARATION
  • JAVA & PYTHON

ADDRESS

B-54, Krishna Bhawan, Parag Narain Road, Near Butler Palace Colony Lucknow
Contact:+ 919839520987
Email:info@alexsir.com