Skip to content

Commit

Permalink
refactor(firebaseui): move Firebase calls to ViewModel
Browse files Browse the repository at this point in the history
  • Loading branch information
thatfiredev committed Feb 16, 2023
1 parent 8fffb30 commit bc9912a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.isGone
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.firebase.ui.auth.AuthUI
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import com.google.android.material.snackbar.Snackbar
import com.google.firebase.quickstart.auth.BuildConfig
import com.google.firebase.quickstart.auth.R
import com.google.firebase.quickstart.auth.databinding.FragmentFirebaseUiBinding
import kotlinx.coroutines.launch

/**
* Demonstrate authentication using the FirebaseUI-Android library. This fragment demonstrates
Expand All @@ -26,7 +28,7 @@ import com.google.firebase.quickstart.auth.databinding.FragmentFirebaseUiBinding
*/
class FirebaseUIFragment : Fragment() {

private lateinit var auth: FirebaseAuth
private val viewModel by viewModels<FirebaseUIViewModel>()

private var _binding: FragmentFirebaseUiBinding? = null
private val binding: FragmentFirebaseUiBinding
Expand All @@ -36,7 +38,7 @@ class FirebaseUIFragment : Fragment() {
// possible customization see: https://github.com/firebase/firebaseui-android
private val signInLauncher = registerForActivityResult(
FirebaseAuthUIActivityResultContract()
) { result -> this.onSignInResult(result)}
) { result -> this.onSignInResult(result) }

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentFirebaseUiBinding.inflate(inflater, container, false)
Expand All @@ -46,62 +48,42 @@ class FirebaseUIFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

// Initialize Firebase Auth
auth = Firebase.auth

binding.signInButton.setOnClickListener { startSignIn() }
binding.signOutButton.setOnClickListener { signOut() }
}

override fun onStart() {
super.onStart()
updateUI(auth.currentUser)
binding.signOutButton.setOnClickListener { viewModel.signOut() }

lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { uiState ->
binding.status.text = uiState.status
binding.detail.text = uiState.detail

binding.signInButton.isGone = !uiState.isSignInVisible
binding.signOutButton.isGone = uiState.isSignInVisible
}
}
}
}

private fun onSignInResult(result: FirebaseAuthUIAuthenticationResult) {
if (result.resultCode == Activity.RESULT_OK) {
// Sign in succeeded
updateUI(auth.currentUser)
} else {
// Sign in failed
Toast.makeText(context, "Sign In Failed", Toast.LENGTH_SHORT).show()
updateUI(null)
Snackbar.make(requireView(), "Sign In Failed", Snackbar.LENGTH_SHORT).show()
}
viewModel.showSignedInUser()
}

private fun startSignIn() {
val intent = AuthUI.getInstance().createSignInIntentBuilder()
.setIsSmartLockEnabled(!BuildConfig.DEBUG)
.setAvailableProviders(listOf(AuthUI.IdpConfig.EmailBuilder().build()))
.setLogo(R.mipmap.ic_launcher)
.build()
.setIsSmartLockEnabled(!BuildConfig.DEBUG)
.setAvailableProviders(listOf(AuthUI.IdpConfig.EmailBuilder().build()))
.setLogo(R.mipmap.ic_launcher)
.build()

signInLauncher.launch(intent)
}

private fun updateUI(user: FirebaseUser?) {
if (user != null) {
// Signed in
binding.status.text = getString(R.string.firebaseui_status_fmt, user.email)
binding.detail.text = getString(R.string.id_fmt, user.uid)

binding.signInButton.visibility = View.GONE
binding.signOutButton.visibility = View.VISIBLE
} else {
// Signed out
binding.status.setText(R.string.signed_out)
binding.detail.text = null

binding.signInButton.visibility = View.VISIBLE
binding.signOutButton.visibility = View.GONE
}
}

private fun signOut() {
AuthUI.getInstance().signOut(requireContext())
updateUI(null)
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.google.firebase.quickstart.auth.kotlin

import androidx.lifecycle.ViewModel
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update

class FirebaseUIViewModel(
private val firebaseAuth: FirebaseAuth = Firebase.auth
) : ViewModel() {
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState

data class UiState(
var status: String = "",
var detail: String? = null,
var isSignInVisible: Boolean = true
)

init {
// Check if user is signed in (non-null) and update UI accordingly.
showSignedInUser()
}

fun showSignedInUser() {
val firebaseUser = firebaseAuth.currentUser
updateUiState(firebaseUser)
}

fun signOut() {
updateUiState(null)
}

private fun updateUiState(user: FirebaseUser?) {
if (user != null) {
_uiState.update { currentUiState ->
currentUiState.copy(
status = "Firebase User: ${user.displayName}",
detail = "Firebase UID: ${user.uid}",
isSignInVisible = false
)
}
} else {
_uiState.update { currentUiState ->
currentUiState.copy(
status = "Signed out",
detail = null,
isSignInVisible = true
)
}
}
}

companion object {
const val TAG = "FirebaseUIViewModel"
}
}

0 comments on commit bc9912a

Please sign in to comment.