• r5_265407
  • 468.6KB
  • zip
  • 0
  • VIP专享
  • 0
  • 2022-04-25 21:02
# Firebase Phone Authentication using Firebase Demo Project to show how to do Phone Authentication in Flutter using Firebase backend. ## Screenshots At First | PhoneNo is entered and submitted :--------------------------------:|:--------------------------------------------------------: ![At First](screenshots/1.jpg) | ![PhoneNo is entered and submitted](screenshots/3.jpg) After OTP is entered & submitted | App is restarted :------------------------------------------------------:|:----------------------------------------: ![After OTP is entered & submitted](screenshots/4.jpg) | ![App is restarted](screenshots/5.jpg) ## Motivation I felt there is no setp-by-step documentation for Firebase Phone Authentication in Flutter. There were couple of implementations on Medium but are out-dated and one article got it but that failed to explain some crucial concepts. AndroidX brought a lot of changes in addition to FlutterFire plugins update. I asked this question on [stackoverflow]( almost 2 years ago, but failed to get step-by-step answer. So I created this demo project. ## Setup Firebase with Flutter You can setup Firebase by following this guide: If you encounter errors with `MultiDex` or `AndroidX` make sure you follow below steps ```gradle // Inside android folder in app level build.gradle file ... android { ... defaultConfig { ... multiDexEnabled true // add this } ... } ... dependencies { // implementation '' // No AndroidX support implementation '' // Add this to support AndroidX ... } ... ``` ## Steps 1. Ask for user's phoneNumber 2. Get OTP from Firebase 3. SignIn to Firebase ## Rules - SignIn/Login is done in the same way. - The OTP is only used to get `AuthCrendential` object - `AuthCredential` 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) ## Workflow 1. User gives the `phoneNumber` 2. Firebase sends OTP 3. SignIn the user - If the SIM card with the `phoneNumber` is not in the device that is currently running the app, - We have to first ask the OTP and get `AuthCredential` object - Next we can use that `AuthCredential` to signIn This method works even if the `phoneNumber` is in the device - Else if user provided SIM phoneNumber is in the device running the app, - We can signIn without the OTP. - because the `verificationCompleted` callback from `submitPhoneNumber` function gives the `AuthCredential` object which is needed to signIn the user - But in the previous case it ain't called because the SIM is not in the phone. ## Functions - SubmitPhoneNumber ```dart Future<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 redable 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 `millisenconds` 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 } ``` - SubmitOTP ```dart 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(); } ``` - SignIn/LogIn ```dart 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()); } } ``` - Logout ```dart 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. ## Contributions - Please feel free to contribute to this README (Pull Requests) and this [stackoverflow answer]( - If you find this `README` useful please star the repository