- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 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.
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();
}
}
});
}
最佳答案
我猜你做错了。
文档中提到的流程:
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.
FirebaseAuth.signInWith
方法,而不是您需要:-
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/
我是一名优秀的程序员,十分优秀!