[英]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.