Flutterexperts

Empowering Vision with FlutterExperts' Expertise
Phone Authentication in Flutter

Things that you may likely learn from the Blog ::

YOU WILL LEARN HOW TO

  • CONNECT YOUR FLUTTER APP WITH FIREBASE
  • GET THE SHA-1 KEY USING GRADLE METHOD
  • ENABLE PHONE AUTHENTICATION
  • IMPLEMENT THE PHONE AUTHENTICATION FUNCTIONALITY
  • CONTROL UI ACCORDING TO THE AUTH STATE

Demo module::


Importance of phone authentication::

— Images sound more than words —

Introduction

Authenticating the user identity using the users mobile phone number is referred to as Phone Authentication. This verification method is very secure. because when we enter our phone number the phone number is verified in the first step and if the phone number is correct or exists then only the OTP is sent to the respective mobile, after the verification of the OTP only the users are allowed to access the app data.


Table of content

  1. Installing dependencies
  2. Connecting app with firebase & Enabling phone auth
  3. Verifying phone number
  4. Signing in using OTP
  5. SignOut
  6. Managing the UI using the auth state
  7. GitHub Link

Installing Dependencies::

firebase_auth | Flutter Package
A Flutter plugin to use the Firebase Authentication API. For Flutter plugins for other Firebase products, see…pub.dev

Edit your pubspec.yaml

dependencies:
firebase_auth:

Connecting app with firebase & Enabling phone auth::

Please refer to “Setting up the project” section to connect your app with firebase. I have explaned everything in detail.

Using Firebase Firestore in Flutter
Fetching data from cloud firestoremedium.com

GET THE SHA-1 KEY USING GRADLE METHOD

Open Android Studio, go to app-level build.gradle file, click on “Open for editing on Android Studio”, click on Gradle tab, go to

  • android->Tasks->android->singingReport
  • You will get the SHA-1 key in the run Tab.
  • Note: Use this key while adding an app with firebase in the “Register app” section.

Enabling phone auth

  • Go to the Authentication section, go to the phone sign-in Provider, and enable it.
  • You can also add a dummy phone number and OTP for testing purposes.

Verifying phone number::

Firebase auth provides us verifyPhoneNumber() to verify the phone number. FirebaseAuth.instance will create a firebase auth instance that will allow us to access various methods. This method takes six properties phoneNumber, timeout, verificationCompleted, verificationFailed, codeSent, codeAutoRetrievalTimeout .

String phoneNumber, verificationId;
String otp, authStatus = "";

Future<void> verifyPhoneNumber(BuildContext context) async {
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: const Duration(seconds: 15),
verificationCompleted: (AuthCredential authCredential) {
setState(() {
authStatus = "Your account is successfully verified";
});
},
verificationFailed: (AuthException authException) {
setState(() {
authStatus = "Authentication failed";
});
},
codeSent: (String verId, [int forceCodeResent]) {
verificationId = verId;
setState(() {
authStatus = "OTP has been successfully send";
});
otpDialogBox(context).then((value) {});
},
codeAutoRetrievalTimeout: (String verId) {
verificationId = verId;
setState(() {
authStatus = "TIMEOUT";
});
},
);
}

We are also displaying the authStautus if the OTP has been successfully sent it will show OTP has been successfully send , if verification Failed then it will show Authentication failed , if your account verification Completed then Your account is successfully verified will be displayed.

Signing in using OTP::

signIn method

We are using a non-Dismissible AltertDialog Box to enter the OTP. After the OTP is entered the OTP will we used as smsCode in the sign-in process.

Future<void> signIn(String otp) async {
await FirebaseAuth.instance
.signInWithCredential(PhoneAuthProvider.getCredential(
verificationId: verificationId,
smsCode: otp,
));
}

verificationId is the id that we receive while verifying the phone number.

Dialog Box

otpDialogBox(BuildContext context) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return new AlertDialog(
title: Text('Enter your OTP'),
content: Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
decoration: InputDecoration(
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(30),
),
),
),
onChanged: (value) {
otp = value;
},
),
),
contentPadding: EdgeInsets.all(10.0),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
signIn(otp);
},
child: Text(
'Submit',
),
),
],
);
});
}

SignOut::

FirebaseAuth.instance provides us signOut() method to signOut the current user.

Future<void> _logout() async {
try {
await FirebaseAuth.instance.signOut();
} catch (e) {
print(e.toString());
}
}

HomePage.dart

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

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
Future<void> _logout() async {
try {
await FirebaseAuth.instance.signOut();
} catch (e) {
print(e.toString());
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Phone Auth Demo"),
backgroundColor: Colors.cyan,
),
body: FutureBuilder(
future: FirebaseAuth.instance.currentUser(),
builder: (context, snapshot) {
FirebaseUser firebaseUser = snapshot.data;
return snapshot.hasData
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"SignIn Success 😊",
style: TextStyle(
color: Colors.green,
fontWeight: FontWeight.bold,
fontSize: 30,
),
),
SizedBox(
height: 20,
),
Text("UserId: ${firebaseUser.uid}"),
SizedBox(
height: 20,
),
Text(
"Registered Phone Number: ${firebaseUser.phoneNumber}"),
SizedBox(
height: 20,
),
RaisedButton(
onPressed: _logout,
child: Text(
"LogOut",
style: TextStyle(color: Colors.white),
),
color: Colors.cyan,
)
],
),
)
: CircularProgressIndicator();
},
),
);
}
}

LoginPage.dart

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

import 'dart:async';

class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
String phoneNumber, verificationId;
String otp, authStatus = "";

Future<void> verifyPhoneNumber(BuildContext context) async {
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: const Duration(seconds: 15),
verificationCompleted: (AuthCredential authCredential) {
setState(() {
authStatus = "Your account is successfully verified";
});
},
verificationFailed: (AuthException authException) {
setState(() {
authStatus = "Authentication failed";
});
},
codeSent: (String verId, [int forceCodeResent]) {
verificationId = verId;
setState(() {
authStatus = "OTP has been successfully send";
});
otpDialogBox(context).then((value) {});
},
codeAutoRetrievalTimeout: (String verId) {
verificationId = verId;
setState(() {
authStatus = "TIMEOUT";
});
},
);
}

otpDialogBox(BuildContext context) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return new AlertDialog(
title: Text('Enter your OTP'),
content: Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
decoration: InputDecoration(
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(30),
),
),
),
onChanged: (value) {
otp = value;
},
),
),
contentPadding: EdgeInsets.all(10.0),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
signIn(otp);
},
child: Text(
'Submit',
),
),
],
);
});
}

Future<void> signIn(String otp) async {
await FirebaseAuth.instance
.signInWithCredential(PhoneAuthProvider.getCredential(
verificationId: verificationId,
smsCode: otp,
));
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height * 0.2,
),
Text(
"Phone Auth demo📱",
style: TextStyle(
color: Colors.cyan,
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
Image.network(
"https://avatars1.githubusercontent.com/u/41328571?s=280&v=4",
height: 150,
),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
keyboardType: TextInputType.phone,
decoration: new InputDecoration(
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(30),
),
),
filled: true,
prefixIcon: Icon(
Icons.phone_iphone,
color: Colors.cyan,
),
hintStyle: new TextStyle(color: Colors.grey[800]),
hintText: "Enter Your Phone Number...",
fillColor: Colors.white70),
onChanged: (value) {
phoneNumber = value;
},
),
),
SizedBox(
height: 10.0,
),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)),
onPressed: () =>
phoneNumber == null ? null : verifyPhoneNumber(context),
child: Text(
"Generate OTP",
style: TextStyle(color: Colors.white),
),
elevation: 7.0,
color: Colors.cyan,
),
SizedBox(
height: 20,
),
Text("Need Help?"),
SizedBox(
height: 20,
),
Text(
"Please enter the phone number followed by country code",
style: TextStyle(color: Colors.green),
),
SizedBox(
height: 20,
),
Text(
authStatus == "" ? "" : authStatus,
style: TextStyle(
color: authStatus.contains("fail") ||
authStatus.contains("TIMEOUT")
? Colors.red
: Colors.green),
)
],
),
),
);
}
}

Managing the UI using the auth state::

FirebaseAuth.instance.onAuthStateChanged provides us the stream of authState. To manage the UI according to the auth state we can use StreamBuilder .

main.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:phone_auth_example/homePage.dart';
import 'signUpPage.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (ctx, userSnapshot) {
if (userSnapshot.hasData) {
return HomePage();
} else if (userSnapshot.hasError) {
return CircularProgressIndicator();
}
return LoginPage();
},
));
}
}

GitHub Link::

flutter-devs/phone_auth_example
A new Flutter application. This project is a starting point for a Flutter application. A few resources to get you…github.com


Who is this course for?

Want to build Flutter apps with native functionalities?

  1. Want to learn advanced Flutter functionality?
  2. Want to learn job-oriented and high-demand, high-paying flutter iOS and android functionality?

What does this course offer?

  1. Flutter Razorpay payment gateway integration: In this module, we shall learn about Razorpay payment gateway integration which will help us to process the payment of the purchases made by the user.
  2. Flutter Stripe payment gateway integration: In this module, we shall learn about Stripe payment gateway integration which will help us to process the payment of the purchases made by the user.
  3. FLUTTER SCAN AND GENERATE QR CODE: In this module, we shall learn how we can scan a QR code and generate the QR code in Flutter.
  4. FLUTTER FIREBASE EMAIL PASSWORD AUTHENTICATION: In this module, we will learn how we can perform authentication using an email password provider, we will also learn how we can verify the user’s email and reset the password.
  5. FLUTTER FIREBASE PHONE AUTHENTICATION: In this module, we will learn how we can perform authentication using a phone authentication provider, and we will see how we can send the OTP to the provided phone number and sign in using the phone credentials.
  6. FLUTTER FIREBASE GOOGLE AUTHENTICATION: In this module, we will learn how to perform authentication using the google authentication provider using firebase in flutter.

Feel free to connect with us:
And read more articles from FlutterDevs.com

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter related queries.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences!.

Thank you for reading. 🌸

Leave comment

Your email address will not be published. Required fields are marked with *.