Skip to content

Instantly share code, notes, and snippets.

@MertNYuksel
Created December 18, 2020 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MertNYuksel/15361012930574f7b032acc528000c71 to your computer and use it in GitHub Desktop.
Save MertNYuksel/15361012930574f7b032acc528000c71 to your computer and use it in GitHub Desktop.
GoogleSignInHelperFragment
package com.x.y.authentication
import android.os.Bundle
import android.view.View
import androidx.fragment.app.viewModels
import com.x.y.R
import com.x.y.common.BaseFragment
import com.x.y.common.extensions.observeNonNull
import com.x.y.common.viewBinding
import com.x.y.databinding.FragmentAuthenticationBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class AuthenticationFragment : BaseFragment(R.layout.fragment_authentication) {
val binding: FragmentAuthenticationBinding by viewBinding(FragmentAuthenticationBinding::bind)
val viewModel: AuthenticationViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonLogin.setOnClickListener {
GoogleSignInUseHeadlessFragment
.getSignInFragment(childFragmentManager)
.signIn()
}
GoogleSignInUseHeadlessFragment
.getSignInFragment(childFragmentManager)
.apply {
this.authenticationFailedListener = {
viewModel.onAuthenticationFailed(it)
}
this.userAuthenticatedListener = { viewModel.onUserAuthenticatedWithGoogle(it) }
}
}
}
package com.x.y.authentication
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.x.y.R
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.ApiException
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
class GoogleSignInHelperFragment : Fragment() {
private val RC_SIGN_IN = 42
var authenticationFailedListener: ((Exception) -> Unit)? = null
var userAuthenticatedListener: ((FirebaseUser) -> Unit)? = null
var authenticationCancelledListener: (() -> Unit)? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true
}
fun signIn() {
val options = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(requireActivity().getString(R.string.default_web_client_id))
.requestEmail()
.build()
val client = GoogleSignIn.getClient(requireContext(), options)
val signInIntent = client.signInIntent
startActivityForResult(signInIntent, RC_SIGN_IN)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN) {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
try {
val account = task.getResult(ApiException::class.java)
firebaseAuthWithGoogle(requireNotNull(account?.idToken))
} catch (e: Exception) {
renderError(e)
}
}
}
private fun firebaseAuthWithGoogle(idToken: String) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
Firebase.auth.signInWithCredential(credential)
.addOnCompleteListener(requireActivity()) { task ->
val exception = task.exception
when {
task.isSuccessful -> {
onUserAuthenticated(requireNotNull(task.result?.user))
}
task.isCanceled -> {
onAuthenticatedCancelled()
}
exception != null -> {
renderError(exception)
}
}
}
}
private fun renderError(exception: Exception) {
authenticationFailedListener?.invoke(exception)
}
private fun onUserAuthenticated(user: FirebaseUser) {
userAuthenticatedListener?.invoke(user)
}
private fun onAuthenticatedCancelled() {
authenticationCancelledListener?.invoke()
}
companion object {
private val TAG = "GOOGLE_SIGN_IN_TAG"
fun getSignInFragment(fragmentManager: FragmentManager): GoogleSignInUseHeadlessFragment {
return fragmentManager.findFragmentByTag(TAG) as GoogleSignInUseHeadlessFragment?
?: GoogleSignInUseHeadlessFragment().apply {
fragmentManager
.beginTransaction()
.add(this, TAG)
.commit()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment