user10522232
user10522232

Reputation:

How to link Phone with Email/Password Authentication?

I am trying to create a flutter app in which after creating a user with email/ password they are saved in the firebase then the user enters his phone number on which OTP is sent and the user is logged in after verification. my problem is that when both of these steps are completed firebase is creating two separate accounts one with email other with the phone. Please tell me how can I create a Single account with Both Email/Password and Phone. I also want to login with both Email/Password or Phone. Or any other way to create a user with email/password and Phone.

void _verifyPhoneNumber() async {
if (mounted)
  setState(() {
    _message = '';
  });
final PhoneVerificationCompleted verificationCompleted =
    (AuthCredential phoneAuthCredential) {
  _firebaseUser.updatePhoneNumberCredential(phoneAuthCredential);
  if (mounted)
    setState(() {
      _message = 'Received phone auth credential: $phoneAuthCredential';
    });
};

 final PhoneVerificationFailed verificationFailed =
    (AuthException authException) {
  showToast(authException.message,
      gravity: Toast.TOP, duration: Toast.LENGTH_LONG);
  if (mounted)
    setState(() {
      _isLoading = false;
      _message =
          'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}';
    });
};

final PhoneCodeSent codeSent =
    (String verificationId, [int forceResendingToken]) async {
  print('Please check your phone for the verification code.');
  _verificationId = verificationId;
  setState(() {
    _isLoading = false;
  });
  Navigator.of(context).pushReplacement(new MaterialPageRoute(
      builder: (BuildContext context) =>
          new VerifyOtp(_firebaseUser, verificationId)));
  };

 final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
    (String verificationId) {
  _verificationId = verificationId;
};

await _firebaseAuth.verifyPhoneNumber(
    phoneNumber: phoneController.text,
    timeout: const Duration(minutes: 2),
    verificationCompleted: verificationCompleted,
    verificationFailed: verificationFailed,
    codeSent: codeSent,
    codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);
}

Verification*

   final AuthCredential credential = PhoneAuthProvider.getCredential(
    verificationId: widget.verificationId,
    smsCode: otpController.text,
  );

await _firebaseAuth.signInWithCredential(credential).then((user) {

  }).catchError((error) {
    showToast(error.toString(),
        gravity: Toast.TOP, duration: Toast.LENGTH_LONG);

  });

Upvotes: 7

Views: 5787

Answers (2)

Gursewak Singh
Gursewak Singh

Reputation: 280

 await _firebaseAuth.signInWithCredential(credential).then((user) {

}).catchError((error) {
  showToast(error.toString(),
    gravity: Toast.TOP, duration: Toast.LENGTH_LONG);

});

Just replace it with

firebaseUser.linkWithCredential(credential).then((user) {
    print(user.uid);
  }).catchError((error) {
    print(error.toString());
  });

This is work for me.....

Upvotes: 6

Umar Hussain
Umar Hussain

Reputation: 3527

You need to link the phone auth provider to the firebase user object after email password signin. https://firebase.google.com/docs/auth/android/account-linking. Since you are directly calling sign in, firebase will consider it as a new signin/signup, creating new account.

You may be adding phone auth to user in settings page of your app, when you have created AuthCredential simply call firebaseUser.linkWithCredential() equivalent in flutter and it will connect the phone auth to the user.

You can verify it from firebase console where phone and mail logo will appear against user's email.

Upvotes: 1

Related Questions