Firebase 一次发出 3 个请求 MVVM
Firebase make 3 requests at a time MVVM
所以我开始构建一个聊天应用程序,现在我在注册屏幕上。
每次我按下登录按钮,请求只发送 1 次,就像它应该做的那样。
当我收到 return 错误消息(例如“您的密码不正确”)时,问题就开始了,在我收到错误消息后,我再次使用相同的错误密码按下登录按钮,然后我收到日志错误我做了,但同时显示了 3 次,firebase 告诉我我尝试了太多次....
这是我所做的:
视图模型:
private val _authState by lazy { MutableLiveData<AuthState>(AuthState.Loading) }
val authState: LiveData<AuthState> = _authState
fun loginUser(emailAddress: String, password: String) {
if (!isEmailAddressValid(emailAddress)) {
_authState.value = AuthState.AuthError("Invalid email")
return
} else if (password.isEmpty()) {
_authState.value = AuthState.AuthError("Password field can't be empty")
return
} else if (emailAddress.isEmpty()) {
_authState.value = AuthState.AuthError("Email field can't be empty")
return
}
auth.signInWithEmailAndPassword(emailAddress, password).addOnCompleteListener { task ->
if (task.isSuccessful) {
_authState.value = AuthState.Success
} else {
task.exception?.let {
_authState.value = AuthState.AuthError(it.localizedMessage)
}
}
}
}
这是Activity:
binding.loginButton.setOnClickListener {
val emailEditText = binding.emailAddressEditText.text.toString()
val passwordEditText = binding.passwordEditText.text.toString()
registerLoginViewModel.loginUser(emailEditText, passwordEditText)
registerLoginViewModel.authState.observe(this@LoginRegisterActivity, object : Observer<AuthState?> {
override fun onChanged(loginState: AuthState?) {
when (loginState) {
is AuthState.Success -> {
hideLoadingScreen()
Toast.makeText(this@LoginRegisterActivity,"Welcome Back!",Toast.LENGTH_SHORT).show()
Intent(this@LoginRegisterActivity, MainActivity::class.java)
finish()
}
is AuthState.AuthError -> {
hideLoadingScreen()
Log.e("Error:","Error Message: ${loginState.message}") // This line returns 3 times after the second attempt
Toast.makeText(this@LoginRegisterActivity,loginState.message,Toast.LENGTH_SHORT).show()
}
else -> {
showLoadingScreen()
}
}
}
})
}
谢谢!
LiveData.observe(...)
不需要在任何类型的侦听器中。您可以在 API 调用之前在 Activity 的 onCreate()
中观察。正如现在在您的代码中一样,每次调用点击侦听器时,您都会添加一个新的观察者。
这是一个小例子:
class FruitsActivity : AppCompatActivity {
private val binding by lazy {
FruitsActivityBinding.inflate(layoutInflater)
}
private val fruitsViewModel by viewModels<FruitsViewModel>()
@Override
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
// Observe from fruitsViewModel.fruits
fruitsViewModel.fruits.observe(this) { fruitList ->
// Use `fruitList` in your adapter
}
// Fetch fruits on tap of a button
binding.loadFruitsButton.setOnClickListener {
fruitsViewModel.fetchFruits()
}
}
}
class FruitsViewModel : ViewModel() {
private val _fruits = MutableLiveData<List<Fruit>>()
val fruits: LiveData<List<Fruit>> = _fruits
fun fetchFruits() {
viewModelScope.launch {
// `someRepository` can be anything that calls an API
// or queries a database to get the required data.
// Repository Pattern + Coroutines recommended
val fruitList = someRepository.fetchFruits()
// if needed, perform any filters or modifications to `fruitList` here
// set the result data on LiveData
_fruits.value = fruitList
}
}
}
所以,这就是发生的事情:
- Activity 发布。
- 初始化
binding
和 fruitsViewModel
。
- 从
fruitsViewModel
fruits
添加 Observer
- 在加载水果的按钮上设置点击监听器
- 当您点击按钮时,
fruitsViewModel
获取水果并在 LiveData (_fruits
) 上设置结果数据。
- LiveData 找到它的观察者并通知他们有关新数据的信息。
如果您有任何问题或有任何问题,请告诉我。我直接在这个文本字段中编写了代码,因此可能有一个点、逗号或冒号错放或丢失。
所以我开始构建一个聊天应用程序,现在我在注册屏幕上。
每次我按下登录按钮,请求只发送 1 次,就像它应该做的那样。 当我收到 return 错误消息(例如“您的密码不正确”)时,问题就开始了,在我收到错误消息后,我再次使用相同的错误密码按下登录按钮,然后我收到日志错误我做了,但同时显示了 3 次,firebase 告诉我我尝试了太多次....
这是我所做的:
视图模型:
private val _authState by lazy { MutableLiveData<AuthState>(AuthState.Loading) }
val authState: LiveData<AuthState> = _authState
fun loginUser(emailAddress: String, password: String) {
if (!isEmailAddressValid(emailAddress)) {
_authState.value = AuthState.AuthError("Invalid email")
return
} else if (password.isEmpty()) {
_authState.value = AuthState.AuthError("Password field can't be empty")
return
} else if (emailAddress.isEmpty()) {
_authState.value = AuthState.AuthError("Email field can't be empty")
return
}
auth.signInWithEmailAndPassword(emailAddress, password).addOnCompleteListener { task ->
if (task.isSuccessful) {
_authState.value = AuthState.Success
} else {
task.exception?.let {
_authState.value = AuthState.AuthError(it.localizedMessage)
}
}
}
}
这是Activity:
binding.loginButton.setOnClickListener {
val emailEditText = binding.emailAddressEditText.text.toString()
val passwordEditText = binding.passwordEditText.text.toString()
registerLoginViewModel.loginUser(emailEditText, passwordEditText)
registerLoginViewModel.authState.observe(this@LoginRegisterActivity, object : Observer<AuthState?> {
override fun onChanged(loginState: AuthState?) {
when (loginState) {
is AuthState.Success -> {
hideLoadingScreen()
Toast.makeText(this@LoginRegisterActivity,"Welcome Back!",Toast.LENGTH_SHORT).show()
Intent(this@LoginRegisterActivity, MainActivity::class.java)
finish()
}
is AuthState.AuthError -> {
hideLoadingScreen()
Log.e("Error:","Error Message: ${loginState.message}") // This line returns 3 times after the second attempt
Toast.makeText(this@LoginRegisterActivity,loginState.message,Toast.LENGTH_SHORT).show()
}
else -> {
showLoadingScreen()
}
}
}
})
}
谢谢!
LiveData.observe(...)
不需要在任何类型的侦听器中。您可以在 API 调用之前在 Activity 的 onCreate()
中观察。正如现在在您的代码中一样,每次调用点击侦听器时,您都会添加一个新的观察者。
这是一个小例子:
class FruitsActivity : AppCompatActivity {
private val binding by lazy {
FruitsActivityBinding.inflate(layoutInflater)
}
private val fruitsViewModel by viewModels<FruitsViewModel>()
@Override
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
// Observe from fruitsViewModel.fruits
fruitsViewModel.fruits.observe(this) { fruitList ->
// Use `fruitList` in your adapter
}
// Fetch fruits on tap of a button
binding.loadFruitsButton.setOnClickListener {
fruitsViewModel.fetchFruits()
}
}
}
class FruitsViewModel : ViewModel() {
private val _fruits = MutableLiveData<List<Fruit>>()
val fruits: LiveData<List<Fruit>> = _fruits
fun fetchFruits() {
viewModelScope.launch {
// `someRepository` can be anything that calls an API
// or queries a database to get the required data.
// Repository Pattern + Coroutines recommended
val fruitList = someRepository.fetchFruits()
// if needed, perform any filters or modifications to `fruitList` here
// set the result data on LiveData
_fruits.value = fruitList
}
}
}
所以,这就是发生的事情:
- Activity 发布。
- 初始化
binding
和fruitsViewModel
。 - 从
fruitsViewModel
- 在加载水果的按钮上设置点击监听器
- 当您点击按钮时,
fruitsViewModel
获取水果并在 LiveData (_fruits
) 上设置结果数据。 - LiveData 找到它的观察者并通知他们有关新数据的信息。
fruits
添加 Observer
如果您有任何问题或有任何问题,请告诉我。我直接在这个文本字段中编写了代码,因此可能有一个点、逗号或冒号错放或丢失。