繁体   English   中英

如何绑定Email的手机和Firebase的密码认证?

[英]How to link Phone with Email and Password Authentication in Firebase?

我正在尝试创建一个应用程序,用户可以在其中使用用户名和密码进行注册,然后输入电话号码、接收 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()
                }
            }
        }
}

如果您这样做,Firebase 会创建两个不同的用户。

这是预期的行为,因为您使用的是两种不同类型的身份验证。

如何将它们组合起来以使其显示为单个帐户?

如果您只想拥有一个,那么您应该将它们链接到一个帐户中。 根据有关 帐户链接的官方文档,首先,您需要获取现有凭据:

val authCredential = EmailAuthProvider.getCredential(email, password)

对于 Java 用户:

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

然后简单地使用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)
    }
}

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

对我有用的是updatePhoneNumber() ,而不是使用,

linkWithCredential()

val auth = FirebaseAuth.getInstance() auth.currentUser...linkWithCredential(credential).addOnCompleteListener(this){ }你可以使用

更新电话号码()

val auth = FirebaseAuth.getInstance() auth.currentUser?.updatePhoneNumber(credential).addOnCompleteListener(this){ }因为它是您要与 Email 和密码合并的电话号码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM