【问题标题】:LinkWithCredentials process help for creating single account for userLinkWithCredentials 流程帮助为用户创建单个帐户
【发布时间】:2021-01-15 17:00:49
【问题描述】:

我正在构建一个应用程序,要求用户填写注册屏幕的详细信息。一旦他们填写了所有详细信息并验证了详细信息,我就允许他们输入他们的电子邮件 ID。验证电子邮件 ID 后(1. 空白电子邮件 2. 无效电子邮件 ID 3. 通过 Firebase 检查现有电子邮件 ID)然后应用程序将为用户创建电子邮件(使用电子邮件密码)。创建电子邮件有 3 个阶段。

  • A.电子邮件创建本身和
  • 乙。向用户发送验证电子邮件。
  • C.等到用户验证电子邮件。

验证电子邮件后,我允许用户输入手机号码。在填写移动验证时会发生(1. 空白移动 2. 无效移动号 3. 通过 Firebase 进行现有移动检查)。如果验证结果是肯定的,我要求他们通过 OTP(新活动)验证手机。经过OTP验证,最后,我将所有用户的数据存储到firebase(密码除外)。

我的实际问题在这里。我希望用户通过电话 OTP 流程或电子邮件密码流程登录。目前,我无法链接用户的电子邮件和电话,因为 Firebase 正在考虑作为 2 个帐户。在谷歌上,我知道我必须使用LinkWithCredential 选项进行链接。但是,它不起作用...

这是我的VerifyOTP 代码,用于进行电话身份验证...

public class VerifyOTP extends AppCompatActivity {
@BindView(R.id.PinViewUser)
PinView PinViewUser;
@BindView(R.id.btnVerify)
Button btnVerify;
@BindView(R.id.btnGetOTP)
Button btnGetOTP;
@BindView(R.id.btnResend)
Button btnResend;
@BindView(R.id.txtCodeVerificationText)
TextView txtCodeVerificationText;
@BindView(R.id.Verificationlabel)
TextView Verificationlabel;
@BindView(R.id.txtNoteToUser)
TextView txtNoteToUser;
FirebaseAuth mAuth;
AuthCredential emailCredential;
String  UserPhoneNo, CodeBySystem, PhNoThroughSignUp, PhNoThroughForgotPassword, ForwardEmailToNextClass, GetCredEmail, GetCredPass;
PhoneAuthProvider.ForceResendingToken mResendToken;
private static final String TAG = "AnonymousAuth";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    RunAppOnFullScreenMode();
    setContentView(R.layout.activity_verify_o_t_p);
    ButterKnife.bind(this);
    //get Ph No & Other Details from SignupLayout
    PhNoThroughSignUp = getIntent().getStringExtra(ReUsuableCode.CustomMobileNo);
    GetCredEmail = getIntent().getStringExtra("CredEmail");
    GetCredPass = getIntent().getStringExtra("CredPass");

    emailCredential = EmailAuthProvider.getCredential(GetCredEmail, GetCredPass);
    //get Ph No from ForgotPassword
    PhNoThroughForgotPassword = getIntent().getStringExtra("FPMobile");

    if (PhNoThroughSignUp == null) {
        UserPhoneNo = PhNoThroughForgotPassword;
    } else {
        UserPhoneNo = PhNoThroughSignUp;
    }
    Toast.makeText(this, "Email: " + GetCredEmail + "Password: " + GetCredPass + "Phone: " + UserPhoneNo, Toast.LENGTH_LONG).show();// this is working
    txtCodeVerificationText.setText("Click On Get OTP Button to Get the OTP on the Mentioned Phone No\n\n Note: Standard SMS charges May Apply");
    Log.d(TAG, "DetailsCollected");
    // Initialize Firebase Auth
    mAuth = FirebaseAuth.getInstance();

    //Send OTPCode to User
    btnGetOTP.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            SendVerificationCodeToUser(UserPhoneNo);
            Log.d(TAG, "Verification Code Sent");
            txtNoteToUser.setVisibility(View.VISIBLE);
            txtCodeVerificationText.setText("Enter the One Time Password received on\n " + UserPhoneNo);
            Toast.makeText(VerifyOTP.this, "OTP Initiated!! Wait For Auto Verification of OTP", Toast.LENGTH_SHORT).show();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    btnVerify.setVisibility(View.VISIBLE);
                }
            }, 10000); // where 1000 is equal to 1 sec (1 * 1000)
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    btnResend.setVisibility(View.VISIBLE);
                }
            }, 60000); // where 1000 is equal to 1 sec (1 * 1000)
        }
    });

    //ReSend OTPCode to User
    btnResend.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            resendVerificationCode(UserPhoneNo, mResendToken);
            txtCodeVerificationText.setText("Resent verification code to " + UserPhoneNo + "\n\n Note: Standard SMS charges May Apply");
            btnResend.setVisibility(View.INVISIBLE);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    btnResend.setVisibility(View.VISIBLE);
                }
            }, 60000); // where 1000 is equal to 1 sec (1 * 1000)
        }
    });

    //Manual Click on VerifyButton
    btnVerify.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String code = PinViewUser.getText().toString();
            if (ReUsuableCode.fieldisEmpty(code)) {
                PinViewUser.setError("Field is Empty");
            } else {
                VerifyCode(CodeBySystem, code);
            }
        }
    });

}

//======================================= Other Private Codes==================
private void SendVerificationCodeToUser(String phNo) {
    PhoneAuthOptions options =
            PhoneAuthOptions.newBuilder(mAuth)
                    .setPhoneNumber(phNo)       // Phone number to verify
                    .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
                    .setActivity(this)                 // Activity (for callback binding)
                    .setCallbacks(mCallbacks)          // OnVerificationStateChangedCallbacks
                    .build();
    PhoneAuthProvider.verifyPhoneNumber(options);
}


public void linkCredential(AuthCredential credential) {
    mAuth.getCurrentUser().linkWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "linkWithCredential:success");
                        FirebaseUser user = task.getResult().getUser();
                        Toast.makeText(VerifyOTP.this, "linkWithCredential:success", Toast.LENGTH_SHORT).show();
                        if (PhNoThroughSignUp == null) {
                            Intent GoToAnotherLayout1 = new Intent(VerifyOTP.this, SetPassword.class);
                            ForwardEmailToNextClass = getIntent().getStringExtra("FEmail");
                            GoToAnotherLayout1.putExtra("FEmail", ForwardEmailToNextClass);
                            startActivity(GoToAnotherLayout1);
                            finish();
                        } else {
                            Intent GoToAnotherLayout1 = new Intent(VerifyOTP.this, Retailer_SignUP.class);
                            GoToAnotherLayout1.putExtra(ReUsuableCode.MobileRegistration, "Mobile Validation Successful");
                            setResult(RESULT_OK, GoToAnotherLayout1);
                            finish();
                        }

                    } else {
                        Log.w(TAG, "linkWithCredential:failure", task.getException());
                        Toast.makeText(VerifyOTP.this, "linkWithCredential:failure" + task.getException().toString(), Toast.LENGTH_SHORT).show();
                    }
                }
            });
}

private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks =
        new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
    @Override
    public void onCodeSent(@NonNull String s, @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
        super.onCodeSent(s, forceResendingToken);
        // Save verification ID and resending token so we can use them later
        CodeBySystem = s;
        mResendToken = forceResendingToken;
        Log.d(TAG, "OnCode Completed");
    }

    @Override
    public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
        Log.d(TAG, "On Verification start");
        Toast.makeText(VerifyOTP.this, "OTP Verification Successful", Toast.LENGTH_SHORT).show();
        String code = phoneAuthCredential.getSmsCode();
        if (code != null) {
            PinViewUser.setText(code);
            VerifyCode(CodeBySystem, code);
            Log.d(TAG, "Pre Link State");
            linkCredential(emailCredential);
            Log.d(TAG, "Post Link State");
        }
    }

    @Override
    public void onVerificationFailed(@NonNull FirebaseException e) {
        Log.d(TAG, "Verification Failed");
        if (e instanceof FirebaseAuthInvalidCredentialsException) {
            Toast.makeText(VerifyOTP.this, "Failed to Verify!! Try After Some Time...", Toast.LENGTH_SHORT).show();
            return;
        } else if (e instanceof FirebaseTooManyRequestsException) {
            Toast.makeText(VerifyOTP.this, "Too Many Attempts!! Try After Some Time...", Toast.LENGTH_SHORT).show();
            return;
        } else {
            Toast.makeText(VerifyOTP.this, "Some Other Error Occured...", Toast.LENGTH_SHORT).show();
            return;
        }
    }
};

private void VerifyCode(String verificationId, String code) {
    PhoneAuthCredential Credential = PhoneAuthProvider.getCredential(verificationId, code);
    Log.d(TAG, "Verified Code");
}


// [START resend_verification]
private void resendVerificationCode(String phoneNumber,
                                    PhoneAuthProvider.ForceResendingToken token) {
    PhoneAuthOptions options =
            PhoneAuthOptions.newBuilder(mAuth)
                    .setPhoneNumber(phoneNumber)       // Phone number to verify
                    .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
                    .setActivity(this)                 // Activity (for callback binding)
                    .setCallbacks(mCallbacks)          // OnVerificationStateChangedCallbacks
                    .setForceResendingToken(token)     // ForceResendingToken from callbacks
                    .build();
    PhoneAuthProvider.verifyPhoneNumber(options);
}

这是我的错误日志:

请在我失踪的地方指导我。如何为用户创建一个帐户?

【问题讨论】:

    标签: android firebase-authentication


    【解决方案1】:

    我能够得到我的代码的答案。这是我提到的修复代码的网站:Learning Path for Linking Phone and Email

    与 Firebase 的第二个身份验证提供者链接的步骤:

    根据我的情况,我首先让用户输入一个电子邮件 ID,因此我让用户首先使用电子邮件 ID 和密码登录,这不过是,

    1. 使用电子邮件和密码创建帐户
    2. 发送验证电子邮件(可选步骤)
    3. 等待用户验证电子邮件 ID(可选步骤)
    4. 使用第一个身份验证提供程序 (EmailAuthProvider) 登录用户。

    签名过程完成后。我让用户输入一个手机号码,以便他可以继续验证电话号码。在此遵循以下过程

    1. 向用户手机发送验证码

    2. onVerificationCompleted的回调方法中。您必须使用 Linkwithcredentials(phcredentials) 而不是使用 phAuth 提供程序进行常规登录 即:

      一)

      PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
      

      b)

      linkCredential(PhCredential);
      
    3. 如果您使用的是手动验证 OTP,请将 2a 和 2b 步骤也链接到 verifybtn

      public void linkCredential(AuthCredential credential) {
          mAuth.getCurrentUser().linkWithCredential(credential)
                  .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                      @Override
                      public void onComplete(@NonNull Task<AuthResult> task) {
                          if (task.isSuccessful()) {
                              Log.d(TAG, "linkWithCredential:success");
      
      
                          } else {
                              Log.w(TAG, "linkWithCredential:failure", task.getException());
                              Toast.makeText(VerifyOTP.this, "linkWithCredential:failure" + task.getException().toString(), Toast.LENGTH_SHORT).show();
                          }
                      }
                  });
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-11
      相关资源
      最近更新 更多