'Auto detect firebase Phone Auth sms code in Flutter
Please read properly and then comment, hope this help full for software community.
I unable to auto detect firebase phone auth
sms, when i test in android
it's work without doing anything, but when i tried it in flutter
sms not detected automatically, require manually type sms code, I did not find any documentation to do this process automatically.
I wan't to know how to detect automatically that sms code from Firebase phone auth
Future<void> verifyPhone() async {
starTimer();
phoneNumber = contryCode+mobile_controller.text;
final PhoneCodeAutoRetrievalTimeout autoReRetrive = (String verId) {
this.verificationId = verId;
};
final PhoneCodeSent smsCodesent = (String verId, [int forceCodeResent]) {
this.verificationId = verId;
pageController.animateToPage(2, duration: Duration(milliseconds: 300), curve: Curves.easeInBack);
/*smsCodeDialog(context).then((value) {
print("VERIFY PHONE SIGN IN");
});
*/
};
final PhoneVerificationCompleted phoneVerificationCompleted =
(PhoneAuthCredential creditional) {
print("VERIFY PHONE AUTH SUCESS");
this.mPhoneCreditional=creditional;
//_controller.animateToPage(3, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
loginIn(creditional);
};
final PhoneVerificationFailed phoneVerificationFailed =
(FirebaseAuthException excepton) {
Fluttertoast.showToast(
msg: excepton.message,
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
print("VERIFY PHONE AUTH FAILED " + excepton.message);
};
FirebaseAuth mAuth=await FirebaseAuth.instance;
mAuth.setLanguageCode("en");
await mAuth.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: const Duration(seconds: 45),
verificationCompleted: phoneVerificationCompleted,
verificationFailed: phoneVerificationFailed,
codeSent: smsCodesent,
codeAutoRetrievalTimeout: autoReRetrive);
}
Solution 1:[1]
Make sure you have added the debugging, release, sha1, sha256 keys to your firebase project.
Make sure you have enabled appcheck enabled on your firebase project.
Make sure you have enabled the Android Device Verification api on your google cloud console.
The below code is slightly modified from the example code given in firebase auth plugin, for my projects the detecion is working well. Some devices may fail to detect the otp, but most of the devices will login automatically.
The code which detects the sms is highlighted in sendOtpFn()
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:projdebug/Widgets/Widgets.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => LoginPageState();
}
class LoginPageState extends State<LoginPage> {
final FirebaseAuth _auth = FirebaseAuth.instance;
final _phoneNumberController = TextEditingController();
final _smsController = TextEditingController();
String _message = '';
late String _verificationId;
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(onPressed: () {
setState(() {});
}),
body: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.center,
child: const Text(
'Test sign in with phone number',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
TextFormField(
controller: _phoneNumberController,
decoration: const InputDecoration(
labelText: 'Phone number (+x xxx-xxx-xxxx)',
),
validator: (String? value) {
if (value!.isEmpty) {
return 'Phone number (+x xxx-xxx-xxxx)';
}
return null;
},
),
Container(
padding: const EdgeInsets.symmetric(vertical: 16),
alignment: Alignment.center,
child: Button(
icon: Icons.send,
buttonColor: Colors.deepOrangeAccent[700]!,
text: 'Send otp',
onPressed: sendOtpFn,
),
),
TextField(
controller: _smsController,
decoration:
const InputDecoration(labelText: 'Verification code'),
),
Container(
padding: const EdgeInsets.only(top: 16),
alignment: Alignment.center,
child: Button(
icon: Icons.done,
buttonColor: Colors.deepOrangeAccent[400]!,
onPressed: manualSignInFn,
text: 'Confirm otp',
),
),
CrossFade(
show: _auth.currentUser?.uid != null,
child: Button(
icon: Icons.logout,
buttonColor: Colors.deepOrangeAccent[400]!,
onPressed: () async{
await _auth.signOut();
setState(() {});
},
text: 'LogOut',
),
),
Visibility(
visible: _message.isNotEmpty,
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
_message,
style: const TextStyle(color: Colors.red),
),
),
)
],
),
),
),
);
}
// Example code of how to verify phone number
Future<void> sendOtpFn() async {
setState(() {
_message = '';
});
///This is the code snippet which [detects the code from sms automatically]
PhoneVerificationCompleted verificationCompleted =
(PhoneAuthCredential phoneAuthCredential) async {
setState(() {
_message = phoneAuthCredential.smsCode ?? "";
_smsController.text = _message;
});
await _auth.signInWithCredential(phoneAuthCredential);
Widgets.showToast(
'Phone number automatically verified and user signed in: $phoneAuthCredential');
setState(() {});
};
PhoneVerificationFailed verificationFailed =
(FirebaseAuthException authException) {
setState(() {
_message =
'Phone number verification failed. Code: ${authException.code}. '
'Message: ${authException.message}';
});
};
PhoneCodeSent codeSent =
(String verificationId, [int? forceResendingToken]) async {
Widgets.showToast('Please check your phone for the verification code.');
_verificationId = verificationId;
};
PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
(String verificationId) {
_verificationId = verificationId;
};
try {
await _auth.verifyPhoneNumber(
phoneNumber: _phoneNumberController.text,
timeout: const Duration(seconds: 120),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);
} catch (e) {
Widgets.showToast('Time out to Verify Phone Number: $e');
}
}
///Code which will be executed only when a confirm otp button is pressed, ie both phoneNumber & otp is typed by the user manually.
Future<void> manualSignInFn() async {
try {
final PhoneAuthCredential credential = PhoneAuthProvider.credential(
verificationId: _verificationId,
smsCode: _smsController.text,
);
final User user = (await _auth.signInWithCredential(credential)).user!;
Widgets.showToast('Successfully signed in UID: ${user.uid}');
} catch (e) {
print(e);
Widgets.showToast('Failed to sign in');
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |