简体   繁体   English

需要帮助将这段 Google 登录和注册代码从片段转换为片段的 viewModel,以便我可以遵循 MVVM

[英]Need help to convert this chunk of Google Sign in and registration code from fragment to viewModel for fragment so I can follow the MVVM

I need to convert the below chunk of codes to my viewModel so that I can follow the MVVM.我需要将下面的代码块转换为我的 viewModel,以便我可以遵循 MVVM。 I did a lot of googling and see some so;我做了很多谷歌搜索,看到了一些; solutions in StackOverflow which never worked for me and also not for Kotlin especially. StackOverflow 中的解决方案从未对我有用,尤其对 Kotlin 也没有用。

here is the fragment code with all the google authentication code in it:这是包含所有谷歌身份验证代码的片段代码:

class LoginFragment: Fragment() { class 登录片段:片段(){

private var _binding: FragmentLoginBinding? = null
private val binding get() = _binding!!
private val scope = CoroutineScope(CoroutineName("loginFragmentScope"))
private val viewModel by viewModels<LoginViewModel>()

private lateinit var googleSignInClient: GoogleSignInClient

companion object {
    const val TAG = "LoginFragment"
    const val RC_SIGN_IN = 9139;
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    _binding = FragmentLoginBinding.inflate(inflater, container, false)
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    binding.btnContinueWithGoogle.setOnClickListener {
        UiUtils.showProgress(requireContext())
        requestGoogleSignIn()
        signIn()
        UiUtils.hideProgress()
    }

}

private fun requestGoogleSignIn() {
    val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken(getString(R.string.default_web_client_id))
        .requestEmail()
        .build()

    googleSignInClient = GoogleSignIn.getClient(requireActivity(), gso)
}

private fun signIn() {
    val signInIntent = googleSignInClient.signInIntent
    startActivityForResult(signInIntent, RC_SIGN_IN)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    UiUtils.showProgress(requireContext())

    if (requestCode == RC_SIGN_IN) {
        val task = GoogleSignIn.getSignedInAccountFromIntent(data)
        try {

            val account = task.getResult(ApiException::class.java)!!
            Log.d(TAG, "firebaseAuthWithGoogle:" + account.id)
            firebaseAuthWithGoogle(account.idToken!!)
        } catch (e: ApiException) {

            Log.w(TAG, "Google sign in failed", e)
            UiUtils.hideProgress()
            UiUtils.showErrorSnackBar(requireView(), "Google sign in failed", 0)

        }
    }
}

private fun firebaseAuthWithGoogle(idToken: String) {
    val credential = GoogleAuthProvider.getCredential(idToken, null)
    FirestoreAuth().auth.signInWithCredential(credential)
        .addOnCompleteListener(requireActivity()) { task ->
            if (task.isSuccessful) {

                Log.d(TAG, "signInWithCredential:success")
                FirestoreAuth().getUserDetails { user ->
                    FirestoreAuth().registerUserWithEmailAndPassword(user.email, "islamic123") {
                        if (it) {
                            updateUi(FirestoreAuth().auth.currentUser)
                        }
                        UiUtils.hideProgress()
                    }
                    DataStoreUtil(requireActivity()).storeInitialData(
                        user.userId,
                        user.firstName
                    )
                    updateUi(FirestoreAuth().auth.currentUser)
                }

            } else {

                Log.w(TAG, "signInWithCredential:failure", task.exception)
                UiUtils.hideProgress()
            }
        }
}

private fun updateUi(user: FirebaseUser? = null) {
    if (user == null) {
        Log.i(TAG, "User is Null!! Failed!")
        return
    }
    startActivity(Intent(activity, TestActivity::class.java))
}

I guess it makes way more sense to have your logic like this:我想这样的逻辑更有意义:

View: onBtnClick(viewmodel.signIn())查看:onBtnClick(viewmodel.signIn())

Viewmodel: signIn() { FirebaseConnectorClass.doSignIn() } Viewmodel: signIn() { FirebaseConnectorClass.doSignIn() }

FirebaseConnectorClass { FirebaseConnectorClass {

firebaseAuthWithGoogle() firebaseAuthWithGoogle()

} }

EDIT: To break it down very simple, with MVVM you want to divide your UI from the backend repositories.编辑:要将其分解得非常简单,使用 MVVM 您希望将 UI 从后端存储库中分离出来。
The main goal is not to freeze the UI while doing some heavy lifting in the backend.主要目标是在后端做一些繁重的工作时不要冻结 UI。
Therefore you have your view (UI) trigger an event in the viewModel.因此,您的视图 (UI) 在 viewModel 中触发了一个事件。 The viewModel then asks the backend to do the given task.然后 viewModel 要求后端执行给定的任务。 When the backend is finished, it informs the viewModel and the viewModel updates the view (UI).后端完成后,它会通知 viewModel,然后 viewModel 会更新视图 (UI)。 This way your UI stays responsive all the time.这样您的 UI 就会一直保持响应。

Checkout the links of Alex Mamo above to get a better understanding.查看上面 Alex Mamo 的链接以获得更好的理解。

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

相关问题 返回 RESULT_CANCELED 的 Google 登录片段 - Google sign-in fragment returning RESULT_CANCELED 如何将动态 IP 地址添加到 Google Cloud 中的“授权 javascript 来源”列表中,以便将 Google 登录集成到我的 web 应用程序中? - How can I add a dynamic IP address to the "Authorised javascript origins" list in Google Cloud so that I can integrate Google sign-in into my web app? 我需要做哪些更改才能为 DATABRICKS 更改此 python 代码 - What changes i need to do so that i can Change this python code for DATABRICKS 将数据从一个片段传递到另一个片段,从 FirebaseRecyclerAdapter - Passing data from one fragment to another fragment from FirebaseRecyclerAdapter 无法从片段开始活动 - Unable start activity from fragment 如何使用firestore在片段中使用回收器视图对viewModel中的数据进行分页 - how to paginate data in viewModel with recycler view in fragment using firestore 需要帮助访问 AWS Cognito 提供的 URL 的访问代码 - Need help accessing the access code from URL provided by AWS Cognito 如何在已经从 Firestore KOTLIN 获取 arrayList 的片段上实现 SearchView - How to implement SearchView on fragment that is already fetching arrayList from firestore KOTLIN 如何将数据从 Activity 传递到 Fragment KOTLIN? - How to pass data from Activity to Fragment KOTLIN? 如何通过点击通知打开片段? - How to open fragment from the click of the notification?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM