Как прослушать неудачную попытку входа в систему - Kotlin MVVM - PullRequest
0 голосов
/ 18 января 2020

Итак, я последовал совету yoursTruly и создал AuthStateListener в своей деятельности (как описано здесь: https://www.youtube.com/watch?v=6CXUNcsQPgQ&feature=youtu.be).

Это работает очень хорошо, потому что действие просто слушает аутентификацию и переключится на следующее действие, если кто-то войдет в систему, а фрагмент просто вызовет вход в систему (электронная почта, пароль) через ViewModel.

Однако не вижу способа поиска неудачных попыток входа в систему (поэтому пользовательский интерфейс будет выглядеть так, будто он не отвечает).

Моя структура выглядит следующим образом: Активность -> Фрагмент -> ViewModel -> Хранилище .

Я использую привязку данных и навигацию.

Активность

class LoginActivity : AppCompatActivity(), FirebaseAuth.AuthStateListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.login_activity)
    }

    override fun onStart() {
        super.onStart()
        FirebaseAuth.getInstance().addAuthStateListener(this)
    }

    override fun onStop() {
        super.onStop()
        FirebaseAuth.getInstance().removeAuthStateListener(this)
    }

    override fun onAuthStateChanged(firebaseAuth: FirebaseAuth) {

        // Will only fire if state has changed!

        if (FirebaseAuth.getInstance().currentUser == null) {
            Toast.makeText(this,"Welcome to the Locators App!\n\nPlease login to continue", Toast.LENGTH_LONG).show()
            return
        }

        firebaseAuth.currentUser?.getIdToken(true)
            ?.addOnSuccessListener { result ->
                val idToken = result.token
                Toast.makeText(this,"User Signed In", Toast.LENGTH_LONG).show()
                Log.d(TAG, "GetTokenResult result (check this at https://jwt.io/ = $idToken")
                goToSiteActivity()
            }
    }

    private fun goToSiteActivity() {
        val intent = Intent(this, SiteActivity::class.java)
        startActivity(intent)
        finish()
    }
}

Фрагмент

class LoginFragment : Fragment() {

    private lateinit var loginViewModel: LoginViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        val binding: LoginFragmentBinding = DataBindingUtil.inflate(
            inflater, R.layout.login_fragment, container, false)

        binding.apply {
            loginPasswordResetText.setOnClickListener{
                findNavController().navigate(R.id.action_loginFragment_to_loginPasswordResetFragment)
            }
            loginButton.setOnClickListener{
                loginProgressBar.visibility = View.VISIBLE
                val email = loginEmailEditText.text.toString()
                val password = loginPasswordEditText.text.toString()
                if(validateForm(email, password)) {
                    loginViewModel.loginUser(email, password)

                }
                loginProgressBar.visibility = View.GONE

            }
            loginNewUserText.setOnClickListener{
                findNavController().navigate(R.id.action_loginFragment_to_loginUserRegisterFragment)
            }
        }
        return binding.root

    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        loginViewModel = ViewModelProviders.of(requireActivity()).get(LoginViewModel::class.java)
    }


    private fun validateForm(email: String, password: String): Boolean {

        var validForm = true

        if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
            loginEmailEditText.error = "Please enter valid email address!"
            validForm = false
        } else loginEmailEditText.error = null

        if (password.isEmpty()) {
            loginPasswordEditText.error = "Please enter password!"
            validForm = false
        } else loginPasswordEditText.error = null

        Log.d(TAG,"validateForm: (email = $email, password =  $password, validateForm = $validForm)")

        return validForm
    }

}

ViewModel

class LoginViewModel : ViewModel() {

    fun loginUser (email: String, password: String) {
        firestoreRepository.loginUser(email, password)
    }
}

Репозиторий

class FirestoreRepository {

        var firebaseAuth = FirebaseAuth.getInstance()
        var firebaseUser = firebaseAuth.currentUser
        var failedLogin: Boolean = false

        fun loginUser(email: String, password: String) {
                failedLogin = false

                firebaseAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener {
                        if (it.isSuccessful) {
                                // Sign in success, update UI with the signed-in user's information
                                Log.d(TAG, "signInWithEmail:success")

                        } else {
                                // If sign in fails, display a message to the user.
                                Log.d(TAG, "signInWithEmail:failure", it.exception)
                                failedLogin = true
                        }
                }
        }
}

Этот вопрос связан с большим запросом, если вы создаете LiveData в Repo Как вы наблюдаете из ViewModel (т.е. что вы используете в качестве LifeCycleOwner?), но я задам отдельный вопрос ..

1 Ответ

1 голос
/ 18 января 2020

AuthStateListener недостаточно, чтобы определить, когда вход не выполнен. Он будет сообщать вам только об изменении состояния пользователя между входом и выходом из системы.

Вы должны будете использовать результат firebaseAuth.signInWithEmailAndPassword, чтобы определить, не удалось ли выполнить вход. Похоже, у вас уже есть некоторый код для обработки этого случая, но вы не слишком много делаете с ошибкой, кроме установки свойства.

Вместо этого вы должны получить метод loginUser ViewModel LiveData, который получает уведомление, когда вход в систему успешен или неудачен. Вам нужно будет подключить вызов к signInWithEmailAndPassword, чтобы изменить состояние этих LiveData, и вашему представлению придется наблюдать эти LiveData, чтобы при необходимости показать сообщение пользователю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...