[英]How to link Phone with Email and Password Authentication in Firebase?
I am trying to create an application where a user can do registration with a username and password, and then enters a phone number, receives an OTP code, and completes the registration form.我正在尝试创建一个应用程序,用户可以在其中使用用户名和密码进行注册,然后输入电话号码、接收 OTP 代码并填写注册表。 But there is a problem.但有一个问题。 If you do this, Firebase creates two different users.如果这样做,Firebase 会创建两个不同的用户。 How can I combine (join) them so that it appears as a single account?我如何合并(加入)它们以使其显示为一个帐户?
Activity with entering a phone number:输入电话号码的活动:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_signup2)
init()
var phoneNumber: String
mBackBtn.setOnClickListener {
}
mNextBtn.setOnClickListener {
phoneNumber = "+" + mCountyCode!!.selectedCountryCode + mPhoneNumberEd.text.toString()
Toast.makeText(this, phoneNumber, Toast.LENGTH_LONG).show()
sendVerificationCode(phoneNumber)
}
}
private fun sendVerificationCode(phone: String) {
var phoneShadow = phone
Log.d("MyTag", phoneShadow)
val options = PhoneAuthOptions.newBuilder()
.setPhoneNumber(phoneShadow)
.setTimeout(60L, TimeUnit.SECONDS)
.setActivity(this)
.setCallbacks(callbacks)
.build()
PhoneAuthProvider.verifyPhoneNumber(options)
}
private fun init() {
callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
override fun onVerificationCompleted(credential: PhoneAuthCredential) {
Log.d(TAG, "onVerificationCompleted:$credential")
val intent = Intent(applicationContext, Signup3::class.java)
startActivity(intent)
}
override fun onVerificationFailed(e: FirebaseException) {
Log.d(TAG, "onVerificationFailed", e)
Toast.makeText(applicationContext, "Failed", Toast.LENGTH_LONG).show()
}
override fun onCodeSent(verificationId: String, token: PhoneAuthProvider.ForceResendingToken) {
Log.d("MyTag","onCodeSent:$verificationId")
var storedVerificationId: String = verificationId
var resendToken: PhoneAuthProvider.ForceResendingToken = token
val intent = Intent(applicationContext, Signup3::class.java)
intent.putExtra("storedVerificationId", storedVerificationId)
startActivity(intent)
}
}
mNextBtn = findViewById(R.id.signup2_next_btn)
mBackBtn = findViewById(R.id.signup2_back_btn)
mPhoneNumberEd = findViewById(R.id.signup2_phone_number_ed)
mCountyCode = findViewById(R.id.signup2_county_code)
mAuth = FirebaseAuth.getInstance()
}
Activity with entering the code that the phone receives:输入手机收到的代码的活动:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_signup3)
init()
var storedVerificationId = intent.getStringExtra("storedVerificationId").toString()
mConfirmBtn.setOnClickListener {
var code = mPinView.text.toString().trim()
if (code.isEmpty()) {
Toast.makeText(this, "Ты ввёл?", Toast.LENGTH_LONG).show()
} else {
var credential : PhoneAuthCredential = PhoneAuthProvider.getCredential(storedVerificationId!!, code)
signInWithPhoneAuthCredential(credential)
}
}
}
private fun init() {
mConfirmBtn = findViewById(R.id.signup3_confirm_btn)
mPinView = findViewById(R.id.signup3_pin_view)
mAuth = FirebaseAuth.getInstance()
}
private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this) {
if (it.isSuccessful) {
var intent = Intent(this, PhoneConfirmedSignup::class.java)
startActivity(intent)
finish()
} else {
if (it.exception is FirebaseAuthInvalidCredentialsException) {
Toast.makeText(this, "Invalid OTP", Toast.LENGTH_SHORT).show()
}
}
}
}
If you do this, the Firebase creates two different users.如果您这样做,Firebase 会创建两个不同的用户。
That's the expected behavior since you are using two separate types of authentication.这是预期的行为,因为您使用的是两种不同类型的身份验证。
How can I combine them so that it appears as a single account?如何将它们组合起来以使其显示为单个帐户?
If you want to have only one, then you should link both of them together into a single account.如果您只想拥有一个,那么您应该将它们链接到一个帐户中。 According to the official documentation regarding account linking , first, you need to get the existing credentials:根据有关 帐户链接的官方文档,首先,您需要获取现有凭据:
val authCredential = EmailAuthProvider.getCredential(email, password)
For Java users:对于 Java 用户:
AuthCredential authCredential = EmailAuthProvider.getCredential(email, password);
And then simply use the FirebaseUser#linkWithCredential(AuthCredential credential) method like in the following lines of code:然后简单地使用FirebaseUser#linkWithCredential(AuthCredential credential)方法,如以下代码行:
val auth = FirebaseAuth.getInstance()
auth.currentUser!!.linkWithCredential(credential).addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
Log.d(TAG, "linkWithCredential:success")
val user = task.result!!.user
updateUI(user)
} else {
Log.w(TAG, "linkWithCredential:failure", task.exception)
Toast.makeText(this, "Authentication failed.", Toast.LENGTH_SHORT).show()
updateUI(null)
}
}
And for Java users:对于 Java 用户:
FirebaseAuth auth = FirebaseAuth.getInstance();
auth.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();
updateUI(user);
} else {
Log.w(TAG, "linkWithCredential:failure", task.getException());
Toast.makeText(AnonymousAuthActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show();
updateUI(null);
}
}
});
What worked for me was updatePhoneNumber()
, instead of using,对我有用的是updatePhoneNumber()
,而不是使用,
linkWithCredential() linkWithCredential()
val auth = FirebaseAuth.getInstance() auth.currentUser...linkWithCredential(credential).addOnCompleteListener(this){ }
you can use val auth = FirebaseAuth.getInstance() auth.currentUser...linkWithCredential(credential).addOnCompleteListener(this){ }
你可以使用
updatePhoneNumber()更新电话号码()
val auth = FirebaseAuth.getInstance() auth.currentUser?.updatePhoneNumber(credential).addOnCompleteListener(this){ }
As it is phone number that you want to merge with Email and password. val auth = FirebaseAuth.getInstance() auth.currentUser?.updatePhoneNumber(credential).addOnCompleteListener(this){ }
因为它是您要与 Email 和密码合并的电话号码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.