gpt4 book ai didi

android - 如何在 Firebase 中将 emailAndPasswordAuth 与 PhoneAuth 合并?

转载 作者:行者123 更新时间:2023-12-03 13:28:19 31 4
gpt4 key购买 nike

我正在尝试使用 Email and Password 首次登录用户, 然后在它之后,我想要 user's Phone Number也。所以我首先使用他的 EmailAndPasswordAuth 为用户签名。在一个 Activity (自定义登录)上,之后,我在下一个 Activity 中通过他的电话号码登录了用户。但由于它成为同一部手机上的两个帐户,我想将这些谷歌和手机凭据合并到一个帐户中。

然后我尝试关注 https://firebase.google.com/docs/auth/android/account-linking ,但它给了我异常(exception)。

com.google.firebase.FirebaseException: User has already been linked to the given provider.



PhoneAuthActivity.java
String email = intent.getStringExtra("email");
String password = intent.getStringExtra("pass");

Toast.makeText(this, "Email" + email + "Password" + password, Toast.LENGTH_SHORT).show();// this is working

emailCredential = EmailAuthProvider.getCredential(email, password);

mPhoneNumberField = findViewById(R.id.field_phone_number);
mVerificationField = findViewById(R.id.field_verification_code);

mStartButton = findViewById(R.id.button_start_verification);
mVerifyButton = findViewById(R.id.button_verify_phone);
mResendButton = findViewById(R.id.button_resend);

mStartButton.setOnClickListener(this);
mVerifyButton.setOnClickListener(this);
mResendButton.setOnClickListener(this);

mAuth = FirebaseAuth.getInstance();
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
Log.d(TAG, "onVerificationCompleted:" + credential);
signInWithPhoneAuthCredential(credential);
}

@Override
public void onVerificationFailed(FirebaseException e) {
Log.w(TAG, "onVerificationFailed", e);
if (e instanceof FirebaseAuthInvalidCredentialsException) {
mPhoneNumberField.setError("Invalid phone number.");
} else if (e instanceof FirebaseTooManyRequestsException) {
Snackbar.make(findViewById(android.R.id.content), "Quota exceeded.",
Snackbar.LENGTH_SHORT).show();
}
}

@Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
Log.d(TAG, "onCodeSent:" + verificationId);
mVerificationId = verificationId;
mResendToken = token;
}
};
}

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInWithCredential:success");
FirebaseUser user = task.getResult().getUser();
linkCredential(emailCredential);
startActivity(new Intent(PhoneActivity.this, MainActivity.class));
finish();
} else {
Log.w(TAG, "signInWithCredential:failure", task.getException());
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
mVerificationField.setError("Invalid code.");
}
}
}
});
}


private void startPhoneNumberVerification(String phoneNumber) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
}

private void verifyPhoneNumberWithCode(String verificationId, String code) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
signInWithPhoneAuthCredential(credential);
}

private void resendVerificationCode(String phoneNumber,
PhoneAuthProvider.ForceResendingToken token) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks, // OnVerificationStateChangedCallbacks
token); // ForceResendingToken from callbacks
}

private boolean validatePhoneNumber() {
String phoneNumber = mPhoneNumberField.getText().toString();
if (TextUtils.isEmpty(phoneNumber)) {
mPhoneNumberField.setError("Invalid phone number.");
return false;
}
return true;
}

@Override
public void onStart() {
super.onStart();
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser != null) {
}
}

@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.button_start_verification:
if (!validatePhoneNumber()) {
return;
}
startPhoneNumberVerification(mPhoneNumberField.getText().toString());
break;
case R.id.button_verify_phone:
String code = mVerificationField.getText().toString();
if (TextUtils.isEmpty(code)) {
mVerificationField.setError("Cannot be empty.");
return;
}

verifyPhoneNumberWithCode(mVerificationId, code);
break;
case R.id.button_resend:
resendVerificationCode(mPhoneNumberField.getText().toString(), mResendToken);
break;
}

}


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(PhoneActivity.this, "Merged", Toast.LENGTH_SHORT).show();

} else {
Log.w(TAG, "linkWithCredential:failure", task.getException());


Toast.makeText(PhoneActivity.this, "Failed to merge" + task.getException().toString(), Toast.LENGTH_SHORT).show();
}

}
});
}

正如评论所言,我使用了我自己的自定义 phoneAuth,而不是使用 FirebaseUI 提供的那个,请帮助我将这两个帐户合并为一个。

在 firebase 控制台中,它正在形成两个帐户。

Two Accounts on one Phone

最佳答案

我猜你做错了。

文档中提到的流程:

Complete the sign-in flow for the new authentication provider up to, but not including, calling one of the FirebaseAuth.signInWith methods. For example, get the user's Google ID token, Facebook access token, or email and password.



引自 documentation of linking auth provider steps ,有人提到你不应该调用任何 FirebaseAuth.signInWith方法,而不是您需要:-
  • 获取新身份验证提供程序的 AuthCredential
  • 通过AuthCredential反对登录用户的linkWithCredential方法,像这样:
    mAuth.getCurrentUser().linkWithCredential(credential)

  • 由于用户已经与一个身份验证提供者签署,我们不需要再次签署他。我们只需要链接这两个提供商,这样他就可以再次使用其中一个提供商登录。

    正如您的代码流程所示,在验证电话号码后,您将使用 PhoneAuthCredential 再次登录用户。 ,然后您尝试链接 emailCredential ;当前登录的用户已经链接到该用户,因此出现错误。

    这应该是您的 mCallbacks 的代码:
    mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
    @Override
    public void onVerificationCompleted(PhoneAuthCredential credential) {
    Log.d(TAG, "onVerificationCompleted:" + credential);
    linkCredential(credential);
    }

    @Override
    public void onVerificationFailed(FirebaseException e) {
    Log.w(TAG, "onVerificationFailed", e);
    if (e instanceof FirebaseAuthInvalidCredentialsException) {
    mPhoneNumberField.setError("Invalid phone number.");
    } else if (e instanceof FirebaseTooManyRequestsException) {
    Snackbar.make(findViewById(android.R.id.content), "Quota exceeded.",
    Snackbar.LENGTH_SHORT).show();
    }
    }

    @Override
    public void onCodeSent(String verificationId,
    PhoneAuthProvider.ForceResendingToken token) {
    Log.d(TAG, "onCodeSent:" + verificationId);
    mVerificationId = verificationId;
    mResendToken = token;
    }
    };

    这是 linkCredentials方法。
        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(PhoneActivity.this, "Merged", Toast.LENGTH_SHORT).show();
    moveToHome();

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

    关于android - 如何在 Firebase 中将 emailAndPasswordAuth 与 PhoneAuth 合并?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50895856/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com