android - 为什么用户详细信息会从 Firestore 中消失?
问题描述
我正在使用Firebase PhoneAuth
我的应用程序进行用户注册。用户已成功验证并开始使用该应用程序,没有任何问题。但是,我发生过几次用户详细信息从Firestore
数据库中消失的情况,但并非所有用户详细信息都消失了。当我在 中检查集合users
时Firestore
,该用户的文档确实存在,但有些数据消失了,实际上,它已覆盖旧数据,就好像这是新用户注册一样(但是,身份验证下的用户 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()
}
}
解决方案
推荐阅读
- android - 我们在哪里可以找到 crosscall-x3 的模拟器?
- java - Java相关问题类名末尾的<>是什么类型的声明
- java - onFocusChange 事件未按预期工作
- react-native - 为什么我在 react native 中添加 unimodules 时收到控制台警告和错误?
- java - 递归列出所有匹配正则表达式的文件
- android - 如何在从 Json 获取数据到 android 应用程序时删除标签/特殊字母?
- python - 试图找出名字长度最短的名字
- z3py - z3 有等效的算子函数吗?
- reactjs - 验证消息未显示使用简单反应验证器的反应挂钩
- python - 使用 Pandas 从 BestBuy API 扁平化 JSON