How to Get OTP Autofill in Flutter?
Last Updated :
24 Sep, 2023
These days we see several times that as we approach getting signed-in in many applications we need to verify our phone numbers. However, we can do so in mainly two ways: by making a phone call or by an OTP — sent as an SMS to our phone numbers. So in this article, we’re going to discuss how we can fill up the OTP fields of our screen(Flutter UI) automatically as the OTP SMS comes. A sample video is given below to get an idea about what we are going to do in this article.
Step By Step Implementation
Step 1: Set Up Firebase
Create a new project on the Firebase Console (https://console.firebase.google.com/). Add your Android and iOS app to the Firebase project and follow the setup instructions to integrate Firebase SDKs into your Flutter app.
Step 2: Set Up Firebase: Implement Phone Number Verification
Use the firebase_auth package in Flutter to interact with Firebase Authentication. Request the user’s phone number and initiate the OTP verification process. You can use the FirebaseAuth.instance.verifyPhoneNumber method to send an OTP to the user’s phone number.
Step 3: Handle OTP Verification
After sending the OTP, Firebase will send an SMS containing the OTP to the user’s phone. Use the firebase_auth package to handle OTP verification. The verifyPhoneNumber method returns a PhoneVerificationCompleted callback when the verification is complete.
Step 4: Handle Verification Failures
There can be scenarios where OTP verification fails (e.g., wrong OTP entered or network issues). You should handle these cases using the PhoneVerificationFailed and PhoneCodeAutoRetrievalTimeout callbacks.
Step 5: Complete the Authentication Process
Once the OTP is verified successfully, you will receive a verification ID. Use this verification ID along with the user-entered OTP to create a PhoneAuthCredential. Finally, call signInWithCredential from the FirebaseAuth instance to complete the authentication process.
Otp Autofill
Now, add telephony and otp_text_field packages to your project by adding the following lines on pubspec.yaml file:
Dart
telephony: ^0.2.0
otp_text_field: ^1.1.3
|
Here, telephony is to listen to incoming OTP message and otp_text_field packages is for OTP input boxes. Add this permission and tags on AndroidManifest.xml file at android/app/src/main folder:
XML
< manifest >
< uses-permission android:name = "android.permission.RECEIVE_SMS" />
< application >
...
...
< receiver android:name = "com.shounakmulay.telephony.sms.IncomingSmsReceiver"
android:permission = "android.permission.BROADCAST_SMS" android:exported = "true" >
< intent-filter >
< action android:name = "android.provider.Telephony.SMS_RECEIVED" />
</ intent-filter >
</ receiver >
</ application >
</ manifest >
|
Declare the required variables:
Dart
Telephony telephony = Telephony.instance;
OtpFieldController otpbox = OtpFieldController();
|
Listen to the incoming OTP SMS:
Dart
telephony.listenIncomingSms(
onNewMessage: (SmsMessage message) {
print(message.address);
print(message.body);
print(message.date);
String sms = message.body.toString();
if (message.body!.contains( 'yourFirebaseProjectName.firebaseapp.com' )){
String otpcode = sms.replaceAll( new RegExp(r '[^0-9]' ), '' );
otpbox.set(otpcode.split( "" ));
setState(() {
});
} else {
print( "Normal message." );
}
},
listenInBackground: false ,
);
|
Set OTP boxes input on your widget tree(Autofill Otp):
Dart
OTPTextField(
outlineBorderRadius: 10,
controller: otpbox,
length: 6,
width: MediaQuery.of(context).size.width,
fieldWidth: 50,
style: TextStyle(fontSize: 17),
textFieldAlignment: MainAxisAlignment.spaceAround,
fieldStyle: FieldStyle.box,
onCompleted: (pin) {
otp = pin;
},
),
|
Full App Example Code (only after completing firebase auth OTP):
Dart
class OtpPhoneWidget extends StatefulWidget {
const OtpPhoneWidget({
Key? key,
}) : super(key: key);
@override
_OtpPhoneWidgetState createState() => _OtpPhoneWidgetState();
}
class _OtpPhoneWidgetState extends State<OtpPhoneWidget>
with TickerProviderStateMixin {
String otp = '' ;
Telephony telephony = Telephony.instance;
OtpFieldController otpbox = OtpFieldController();
final scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
telephony.listenIncomingSms(
onNewMessage: (SmsMessage message) {
print(message.address);
print(message.body);
String sms = message.body.toString();
if (message.body!.contains( 'yourFirebaseProjectName.firebaseapp.com' )) {
String otpcode = sms.replaceAll( new RegExp(r '[^0-9]' ), '' );
otpbox.set(otpcode.split( "" ));
setState(() {
});
} else {
print( "error" );
}
},
listenInBackground: false ,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text( 'Otp Aut0fill' ),
),
body: Center(
child: Column(
children: [
OTPTextField(
outlineBorderRadius: 10,
controller: otpbox,
length: 6,
width: MediaQuery.of(context).size.width,
fieldWidth: 50,
style: TextStyle(fontSize: 17),
textFieldAlignment: MainAxisAlignment.spaceAround,
fieldStyle: FieldStyle.box,
onCompleted: (pin) {
otp = pin;
},
),
],
),
),
);
}
}
|
Output:
Share your thoughts in the comments
Please Login to comment...