kotlin 如何在Firebase中连接电话与电子邮件和密码认证?

ttp71kqs  于 2023-01-31  发布在  Kotlin
关注(0)|答案(2)|浏览(160)

我正在尝试创建一个应用程序,用户可以使用用户名和密码进行注册,然后输入电话号码,接收OTP代码,并完成注册表单。但有一个问题。如果您这样做,Firebase将创建两个不同的用户。我如何合并(加入)他们,使其显示为一个单一的帐户?
输入电话号码的活动:

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()
}

输入手机收到的验证码的活动:

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()
                }
            }
        }
}
agxfikkp

agxfikkp1#

如果这样做,Firebase将创建两个不同的用户。
这是预期的行为,因为您使用的是两种不同类型的身份验证。
如何将它们组合在一起,使其显示为单个帐户?
如果您只想拥有一个帐户,那么您应该将它们链接到一个帐户中。根据account linking的官方文档,首先,您需要获得现有的凭据:

val authCredential = EmailAuthProvider.getCredential(email, password)

对于Java用户:

AuthCredential authCredential = EmailAuthProvider.getCredential(email, password);

然后只需使用FirebaseUser #linkWithCredential(AuthCredential凭据)方法,如以下代码行所示:

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)
    }
}

对于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);
        }
    }
});
ct3nt3jp

ct3nt3jp2#

对我有效的是updatePhoneNumber(),而不是使用,
使用凭据链接()
val auth = FirebaseAuth.getInstance() auth.currentUser!!.linkWithCredential(credential).addOnCompleteListener(this){ }您可以使用
更新电话号码()
val auth = FirebaseAuth.getInstance() auth.currentUser?.updatePhoneNumber(credential).addOnCompleteListener(this){ }因为它是电话号码,你要与电子邮件和密码合并.

相关问题