0
votes

I am trying to make an app using flutter and firebase. I am using FirebaseAuth for signup and signin. I am taking mobile number and password as input and creating a dummy email with phone number and signing in with firebase auth signInWithEmailPassword. What I want to do is first time user signup I want to send otp to that number and if number verified than I want to register with that dummy email and password. Any Idea how to achieve that. I tried something but user is registering even if the otp is wrong.

 String email = '';
 String password = '';
 String name = '';
 String contact = '';
 String error = '';
 String smsCode = '';
 String verificationId;
 bool loading = false;

 Future<void> verifyPhone() async {
print('Inside verify phone');
final PhoneCodeAutoRetrievalTimeout autoRetrieve = (String verId) {
  this.verificationId = verId;
};

final PhoneCodeSent smsCodeSent = (String verId, [int forceCodeResend]) {
  this.verificationId = verId;
  print('Inside code sent');
  smsCodeDialog(context).then((value) {
    print('Signed in');
  });
};

final PhoneVerificationCompleted verifiedSuccess =
    (AuthCredential credential) {
  print('verified');
};

final PhoneVerificationFailed verificationFailed =
    (AuthException exception) {
  print('${exception.message}');
};

if (_formKey.currentState.validate()) {
  await FirebaseAuth.instance.verifyPhoneNumber(
    phoneNumber: '+91 ' + contact,
    timeout: const Duration(seconds: 10),
    verificationCompleted: verifiedSuccess,
    verificationFailed: verificationFailed,
    codeSent: smsCodeSent,
    codeAutoRetrievalTimeout: autoRetrieve,
  );
}
 }

 Future<bool> smsCodeDialog(BuildContext context) {
return showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return new AlertDialog(
        title: Text('Enter SMS Code'),
        content: TextField(
          onChanged: (value) {
            this.smsCode = value;
          },
        ),
        contentPadding: EdgeInsets.all(10),
        actions: <Widget>[
          TextButton(
              onPressed: () async {
                dynamic result =
                    await _auth.register(email, password, name, contact);
                if (result == null) {
                  Navigator.pop(context);
                  setState(() {
                    loading = false;
                    error = "Already registered or Invalid Details.";
                  });
                } else {
                  Navigator.pop(context);
                  Navigator.pushNamedAndRemoveUntil(
                      context, '/', (Route<dynamic> route) => false);
                }
              },
              child: Text('Register',
                  style: GoogleFonts.abhayaLibre(
                      textStyle: TextStyle(
                          fontSize: 24, color: Colors.green[900]))))
        ],
      );
    });
 }

On form submission I am calling verifyPhone method.

1
Can you show us the code that you wrote ? - ahmetakil
I updated the question. Please check back. - Ravikant Vishwakarma
Where do you check for the sms code, whether if the code is true or not - ahmetakil
How to do that? It's printing verified on correct smscode this means it's automatically comparing, right? - Ravikant Vishwakarma
I implemented a similar system a few months ago but i had to create an AuthCredential with PhoneAuthProvider.getCredential then try to signIn the user with signInWithCredential - ahmetakil

1 Answers

0
votes
Future<bool> signIn() async {
try {
  final AuthCredential credential = PhoneAuthProvider.getCredential(
    verificationId: verificationId,
    smsCode: smsCode,
  );
  final AuthResult userResult =
      await _auth.signInWithCredential(credential);
  final FirebaseUser currentUser = await _auth.currentUser();

  final document =
      Firestore().collection("users").document(currentUser.uid);
  final documentSnapshot = await document.get();
  if (!documentSnapshot.exists) {
    await document.setData({
      "id": currentUser.uid,
      "number": phoneNumber,
    });
  }
  return true;
} catch (e) {
  return false;
}

}

  onPressed: () async {
                                      if (_smsController.text.isEmpty) {
                                        widget.scaffoldKey.currentState
                                            .showSnackBar(SnackBar(
                                          content: Text(
                                              "Please enter your SMS code"),
                                          duration: Duration(seconds: 2),
                                        ));
                                        return;
                                      }

                                      await _auth
                                          .currentUser()
                                          .then((user) async {
                                        await signIn()
                                            .then((bool isSignedIn) async {
                                          if (isSignedIn) {
                                            Navigator.of(context)
                                                .pushAndRemoveUntil();
                                          } else {
                                            widget.scaffoldKey.currentState
                                                .showSnackBar(SnackBar(
                                              content:
                                                  Text("Incorrect Code"),
                                              duration:
                                                  Duration(seconds: 2),
                                            ));
                                          }
                                        });
                                      });
                                    },

Here i can show you a minimal example that also uses firestore to store extra information for the user the onPressed is triggered whenever the SMS dialog's button is pressed