Flutter Firebase Phone Authentication :
Flutter Firebase Phone Authentication is useful to authenticate the user based on the phone number instead of traditional way of email based validation.
Phone number based validation is much easier and more convenient to validate the user by sending the otp the user device and authenticating accurately.
Most of the app’s like food delivery app’s swiggy, zomato travel apps like ola, uber now a days follow this otp based i.e., phone authentication.
This is the safest way so banking related apps, online money transfer or payment apps like G-Pay, Phone Pay, paytm use phone number as user id so phone authentication is must.
In this part of the tutorial we make use of Flutter Firebase Phone Authentication as it is easy for beginners to learn this validation as free tier is available to send otp with a limit of 50 sms/ day.
Flutter Firebase Phone Authentication Video Tutorial :
Explore the following tutorial for in-depth updates.
pubspec.yaml :
Add firebase authentication, firebase core dependencies to get started with flutter firebase phone authentication.
dependencies: flutter: sdk: flutter firebase_auth: ^latest_version firebase_core: ^latest_version
welcome.dart :
Creating a welcome screen so that user can navigate to this screen after successful login.
We have just provided basic structure you may append required data.
import 'package:flutter/material.dart'; class Welcome extends StatelessWidget { const Welcome({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Welcome'), ), ), ); } }
main.dart :
The very first step is to initialize the firebase in our app in the void main declaration with a async method.
Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(App()); }
Declare the controllers and variables required
final otpController = TextEditingController(); final numController = TextEditingController(); final FirebaseAuth auth = FirebaseAuth.instance; String verificationId = "";
Design a user input field for phone number and Otp as below
Padding( padding: EdgeInsets.all(10), child: TextField( decoration: const InputDecoration( border: OutlineInputBorder(), labelText: 'Phone Number', hintText: 'Enter valid number' ), controller: numController, ), ), Padding( padding: EdgeInsets.all(10), child: TextField( obscureText: true, decoration: const InputDecoration( border: OutlineInputBorder(), labelText: 'Password', hintText: 'Enter valid password' ), controller: otpController, ), ),
Add two buttons for submitting data and fetch OTP.
TextButton( onPressed: () { fetchotp(); }, child: const Text("Fetch OTP"), ), TextButton( onPressed: () { verify(); }, child: const Text("Send"), )
Declare a method to fetch the otp as below
Future<void> fetchotp() async { await auth.verifyPhoneNumber( phoneNumber: '+919876543210', verificationCompleted: (PhoneAuthCredential credential) async { await auth.signInWithCredential(credential); }, verificationFailed: (FirebaseAuthException e) { if (e.code == 'invalid-phone-number') { print('The provided phone number is not valid.'); } }, codeSent: (String verificationId, int? resendToken) async { this.verificationId = verificationId; }, codeAutoRetrievalTimeout: (String verificationId) {}, ); }
Declare a method to verify the otp
Future<void> verify() async { PhoneAuthCredential phoneAuthCredential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: otpController.text, ); signInWithPhoneAuthCredential(phoneAuthCredential); }
then
Future<void> signInWithPhoneAuthCredential(PhoneAuthCredential phoneAuthCredential) async { try { final authCredential = await auth.signInWithCredential(phoneAuthCredential); if (authCredential.user != null) { Navigator.push( context, MaterialPageRoute(builder: (context) => const Welcome()), ); } } on FirebaseAuthException catch (e) { print("catch"); } }
Flutter Firebase Phone Authentication Full Code :
Here’s the complete code for Flutter phone authentication, covering everything from initialization to setup.
For a more comprehensive understanding, watch the accompanying video tutorial. This class file offers a detailed guide through every step.
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_firebase_auth/welcome.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(App()); } class App extends StatelessWidget { const App({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text("Login"),), body: const MyApp(), ), ); } } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { var otpController = TextEditingController(); var numController = TextEditingController(); FirebaseAuth auth = FirebaseAuth.instance; String verificationId = ""; void signInWithPhoneAuthCredential( PhoneAuthCredential phoneAuthCredential) async { try { final authCredential = await auth.signInWithCredential(phoneAuthCredential); if (authCredential.user != null) { Navigator.push( context, MaterialPageRoute(builder: (context) => const Welcome())); } } on FirebaseAuthException catch (e) { print("catch"); } } @override Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: EdgeInsets.all(10), child: TextField( decoration: const InputDecoration( border: OutlineInputBorder(), labelText: 'Phone Number', hintText: 'Enter valid number' ), controller: numController, ), ), Padding( padding: EdgeInsets.all(10), child: TextField( obscureText: true, decoration: const InputDecoration( border: OutlineInputBorder(), labelText: 'Password', hintText: 'Enter valid password' ), controller: otpController, ), ), TextButton(onPressed: () { fetchotp(); }, child: const Text("Fetch OTP"),), TextButton(onPressed: () { verify(); }, child: const Text("Send")) ], ), ); } Future<void> verify() async { PhoneAuthCredential phoneAuthCredential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: otpController.text); signInWithPhoneAuthCredential(phoneAuthCredential); } Future<void> fetchotp() async { await auth.verifyPhoneNumber( phoneNumber: '+919876543210', verificationCompleted: (PhoneAuthCredential credential) async { await auth.signInWithCredential(credential); }, verificationFailed: (FirebaseAuthException e) { if (e.code == 'invalid-phone-number') { print('The provided phone number is not valid.'); } }, codeSent: (String verificationId, int? resendToken) async { this.verificationId = verificationId; }, codeAutoRetrievalTimeout: (String verificationId) { }, ); } }
Flutter Firebase Phone Authentication Output :
This screen below depicts the usage of Flutter Phone Authentication.
If you have any questions about this tutorial on Firebase phone authentication, please feel free to ask in the comments below. If you found this tutorial helpful, be sure to like and subscribe for future updates