I have searched many websites and I didn't find a way to implement phone authentication in Flutter using Firebase. Can anyone tell me how to this?
Enable Phone Authentication in Firebase All you have to do is click enabled. Then download the google-services. json file again, and add it the project under android/app . Note: If you want to authenticate using email/password then check this tutorial: Using Firebase Auth In Flutter.
After making Firebase Project from Firebase console, and integrating it with Flutter application, you must enable the Phone sign up method first. For this go in Firebase console, open the Authentication tab from the left panel. Click on the Setup Sign up method and enable the Phone verification.
Well Documented Working Demo project here
Below is the detailed procedure
AuthCrendential
objectAuthCredential
object is the only thing that is used to signIn the user.
It is obtained either from verificationCompleted
callback function in verifyPhoneNumber
or from the PhoneAuthProvider
.(Don't worry if it's confusing, keep reading, you'll get it)
phoneNumber
phoneNumber
is not in the device that is currently running the app,
AuthCredential
objectAuthCredential
to signIn
This method works even if the phoneNumber
is in the deviceverificationCompleted
callback from submitPhoneNumber
function gives the AuthCredential
object which is needed to signIn the userFuture<void> _submitPhoneNumber() async {
/// NOTE: Either append your phone number country code or add in the code itself
/// Since I'm in India we use "+91 " as prefix `phoneNumber`
String phoneNumber = "+91 " + _phoneNumberController.text.toString().trim();
print(phoneNumber);
/// The below functions are the callbacks, separated so as to make code more readable
void verificationCompleted(AuthCredential phoneAuthCredential) {
print('verificationCompleted');
...
this._phoneAuthCredential = phoneAuthCredential;
print(phoneAuthCredential);
}
void verificationFailed(AuthException error) {
...
print(error);
}
void codeSent(String verificationId, [int code]) {
...
print('codeSent');
}
void codeAutoRetrievalTimeout(String verificationId) {
...
print('codeAutoRetrievalTimeout');
}
await FirebaseAuth.instance.verifyPhoneNumber(
/// Make sure to prefix with your country code
phoneNumber: phoneNumber,
/// `seconds` didn't work. The underlying implementation code only reads in `milliseconds`
timeout: Duration(milliseconds: 10000),
/// If the SIM (with phoneNumber) is in the current device this function is called.
/// This function gives `AuthCredential`. Moreover `login` function can be called from this callback
verificationCompleted: verificationCompleted,
/// Called when the verification is failed
verificationFailed: verificationFailed,
/// This is called after the OTP is sent. Gives a `verificationId` and `code`
codeSent: codeSent,
/// After automatic code retrival `tmeout` this function is called
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout,
); // All the callbacks are above
}
void _submitOTP() {
/// get the `smsCode` from the user
String smsCode = _otpController.text.toString().trim();
/// when used different phoneNumber other than the current (running) device
/// we need to use OTP to get `phoneAuthCredential` which is inturn used to signIn/login
this._phoneAuthCredential = PhoneAuthProvider.getCredential(
verificationId: this._verificationId, smsCode: smsCode);
_login();
}
Future<void> _login() async {
/// This method is used to login the user
/// `AuthCredential`(`_phoneAuthCredential`) is needed for the signIn method
/// After the signIn method from `AuthResult` we can get `FirebaserUser`(`_firebaseUser`)
try {
await FirebaseAuth.instance
.signInWithCredential(this._phoneAuthCredential)
.then((AuthResult authRes) {
_firebaseUser = authRes.user;
print(_firebaseUser.toString());
});
...
} catch (e) {
...
print(e.toString());
}
}
Future<void> _logout() async {
/// Method to Logout the `FirebaseUser` (`_firebaseUser`)
try {
// signout code
await FirebaseAuth.instance.signOut();
_firebaseUser = null;
...
} catch (e) {
...
print(e.toString());
}
}
For more details on implementation please refer to the lib/main.dart
file here.
If you found issues, edits are welcome to this answer and to this repo README
Below are the steps:-
Get OTP based on Phone Number:-
void sendOTP(String phoneNumber, PhoneCodeSent codeSent,
PhoneVerificationFailed verificationFailed) {
if (!phoneNumber.contains('+')) phoneNumber = '+91' + phoneNumber;
_firebaseAuth.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: Duration(seconds: 30),
verificationCompleted: null,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: null); }
Use the codeSent function to retrieve verification_id and pass it to OTP screen
void codeSent(String verificationId, [int forceResendingToken]) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Otp(
phoneNumber: _phoneNumber,
verificationId: verificationId,
)));
}
Get user based on verification_id and OTP
Future<bool> verifyOTP(String verificationId, String otp) async {
AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: verificationId,
smsCode: otp,
);
AuthResult result;
try {
result = await _firebaseAuth.signInWithCredential(credential);
} catch (e) {
// throw e;
return false;
}
print(result);
(await result.user.getIdToken()).claims.forEach((k, v) {
print('k= $k and v= $v');
});
if (result.user.uid != null) return true;
return false;
}
For more details watch the below video
https://youtu.be/e5M3EwJJYS4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With