首页 > 解决方案 > 为什么用户详细信息会从 Firestore 中消失?

问题描述

我正在使用Firebase PhoneAuth我的应用程序进行用户注册。用户已成功验证并开始使用该应用程序,没有任何问题。但是,我发生过几次用户详细信息从Firestore数据库中消失的情况,但并非所有用户详细信息都消失了。当我在 中检查集合usersFirestore,该用户的文档确实存在,但有些数据消失了,实际上,它已覆盖旧数据,就好像这是新用户注册一样(但是,身份验证下的用户 UID 保持不变)。例如,默认值为user_type = "customer",如您在fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential). 后来我根据需要更改此值,当发生此问题时,我对此字段和其他字段所做的更改将更改回默认值。

以下是我的代码,SignInWithPhone将从SplashScreen

class SigninWithPhoneActivity: BaseActivity() {

    private lateinit var binding: ActivitySignInWithPhoneBinding
    private lateinit var mAuth: FirebaseAuth
    var code = ""
    var number = ""
    var phoneNumber = ""
    var storedOtpID = ""
    private lateinit var resendToken: PhoneAuthProvider.ForceResendingToken

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySignInWithPhoneBinding.inflate(layoutInflater)
        setContentView(binding.root)
        }

        mAuth = FirebaseAuth.getInstance()

        binding.btnGetOtp.setOnClickListener {

            code = binding.etCountryCode.text.toString().trim()
            number = binding.etMobileNumber.text.toString().trim()
            phoneNumber = code + number

            if (number.isNotEmpty()) {
                binding.etMobileNumber.isEnabled = false
                binding.flOtp.visibility = View.VISIBLE
                binding.btnGetOtp.visibility = View.GONE
                binding.btnSignIn.visibility = View.VISIBLE

                sendVerificationCode(phoneNumber)
            } else {
                Toast.makeText(this, "Please enter a valid mobile number", Toast.LENGTH_LONG).show()
            }
        }

        binding.btnSignIn.setOnClickListener {

            val otp = binding.etOtp.text.toString().trim()

            if (otp.isNotEmpty() || otp.length != 6) {
                verifyVerificationCode(otp)
            } else {
                Toast.makeText(this, "Please enter the OTP received through SMS", Toast.LENGTH_LONG)
                    .show()
            }
        }

    }

    private val mCallBack: PhoneAuthProvider.OnVerificationStateChangedCallbacks =
        object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

            override fun onVerificationCompleted(credential: PhoneAuthCredential) {
                val code = credential.smsCode

                if (code != null) {
                    binding.etOtp.setText(code)
                    binding.pbOtp.visibility = View.GONE
                }
            }

            override fun onVerificationFailed(p0: FirebaseException) {

                binding.etMobileNumber.isEnabled = true
                binding.flOtp.visibility = View.GONE
                binding.btnGetOtp.visibility = View.VISIBLE
                binding.btnSignIn.visibility = View.GONE

                Toast.makeText(this@SigninWithPhoneActivity, "Login Failed", Toast.LENGTH_LONG)
                    .show()
            }

            override fun onCodeSent(otpID: String, token: PhoneAuthProvider.ForceResendingToken) {
                super.onCodeSent(otpID, token)

                Toast.makeText(
                    this@SigninWithPhoneActivity,
                    "OTP is send to your number",
                    Toast.LENGTH_LONG
                ).show()
                storedOtpID = otpID
                resendToken = token
            }
        }

    private fun sendVerificationCode(phoneNumber: String) {

        binding.pbOtp.visibility = View.VISIBLE
        Toast.makeText(this@SigninWithPhoneActivity, "Sending OTP", Toast.LENGTH_LONG).show()

        val options = PhoneAuthOptions.newBuilder(mAuth!!)
            .setPhoneNumber(phoneNumber)
            .setTimeout(60L, TimeUnit.SECONDS)
            .setActivity(this)
            .setCallbacks(mCallBack)
            .build()
        PhoneAuthProvider.verifyPhoneNumber(options)

    }

    private fun verifyVerificationCode(code: String) {

        Toast.makeText(
            this@SigninWithPhoneActivity,
            "Verifying credentials",
            Toast.LENGTH_LONG
        ).show()

        val credential = PhoneAuthProvider.getCredential(storedOtpID, code)
        signInWithPhoneAuthCredential(credential)
    }

    private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
        mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {

                    val firebaseUser: FirebaseUser = task.result!!.user!!
                    val userPreliminaryDetails = User(
                        firebaseUser.uid,
                        user_type = "customer",
                        mobile = binding.etMobileNumber.text.toString()
                    )

                    FirestoreClass().checkIfUserAlreadyExist(
                        this@SigninWithPhoneActivity,
                        firebaseUser.uid,
                        userPreliminaryDetails
                    )

                } else {

                    showErrorSnackBar(task.exception!!.message.toString(), true)

                    if (task.exception is FirebaseAuthInvalidCredentialsException) {

                        binding.etMobileNumber.isEnabled = true
                        binding.flOtp.visibility = View.GONE
                        binding.etOtp.text?.clear()
                        binding.btnGetOtp.visibility = View.VISIBLE
                        binding.btnGetOtp.text = "Resend OTP"
                        binding.btnSignIn.visibility = View.GONE

                        Toast.makeText(this, "OTP entered is wrong", Toast.LENGTH_LONG).show()

                    }
                }
            }
    }

    fun userRegistrationSuccess() {
        finish()
        startActivity(Intent(this, ServiceAreaActivity::class.java))
        Toast.makeText(this, "Signed Up successful", Toast.LENGTH_LONG).show()
    }

    fun userSignInSuccess() {
        finish()
        startActivity(Intent(this, ServiceAreaActivity::class.java))
        Toast.makeText(this, "Signed in successfully", Toast.LENGTH_LONG).show()

    }

}

编辑:

调用以下函数来检查用户是否已经存在并相应地登录或注册新用户。

        fun checkIfUserAlreadyExist(
        activity: SigninWithPhoneActivity, userId: String, userDetails: User
    ) {

        mFireStore.collection("users")
            .whereEqualTo(Constants.USER_ID, userId)
            .get()
            .addOnSuccessListener { document ->
                if (document.documents.size > 0) {
                    activity.userSignInSuccess()
                } else {
                    FirestoreClass().registerUser(activity, userDetails)
                }

            }
            .addOnFailureListener { e ->
                
            }
    }



    private fun registerUser(activity: SigninWithPhoneActivity, userInfo: User) {

    mFireStore.collection(Constants.USERS)
        .document(userInfo.user_id)
        .set(userInfo, SetOptions.merge())
        .addOnSuccessListener {
            activity.userRegistrationSuccess()
        }
        .addOnFailureListener { e ->
            activity.hideProgressDialog()
        }
}

标签: androidkotlingoogle-cloud-firestorefirebase-authentication

解决方案


推荐阅读