Firebase Auth Google Sign-In — Complete Guide
In this tutorial, you'll learn about Firebase Auth Google Sign. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
The Problem
Google Sign-In returns 12500 or 12501 error codes, or the credential is null after a successful Google login.
Wrong Approach ❌
// Missing SHA-1 or web client ID configuration
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id)) // Wrong ID!
.requestEmail()
.build()
// Not handling ActivityResult properly
private fun signIn() {
val intent = googleSignInClient.signInIntent
startActivityForResult(intent, RC_SIGN_IN) // Deprecated! Breaks on config change
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
// May not be called on configuration change
}
Output: Sign-in fails with error code 12500/12501. Activity result lost.
Right Approach ✅
class MainActivity : AppCompatActivity() {
private lateinit var auth: FirebaseAuth
private lateinit var googleSignInClient: GoogleSignInClient
// Activity Result API
private val googleSignInLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
val task = GoogleSignIn.getSignedInAccountFromIntent(result.data)
try {
val account = task.getResult(ApiException::class.java)
firebaseAuthWithGoogle(account.idToken!!)
} catch (e: ApiException) {
Log.w("GoogleSignIn", "Sign in failed", e)
showError("Google sign in failed (${e.statusCode})")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
auth = FirebaseAuth.getInstance()
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id)) // From google-services.json
.requestEmail()
.build()
googleSignInClient = GoogleSignIn.getClient(this, gso)
}
private fun signIn() {
googleSignInLauncher.launch(googleSignInClient.signInIntent)
}
private fun firebaseAuthWithGoogle(idToken: String) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
auth.signInWithCredential(credential)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
val user = auth.currentUser
updateUI(user)
} else {
showError("Authentication failed")
}
}
}
// Link Google account to existing email account
private fun linkGoogleAccount(idToken: String) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
auth.currentUser?.linkWithCredential(credential)
?.addOnCompleteListener { task ->
if (task.isSuccessful) {
// Account linked!
} else {
// Credential already in use by another account
val error = task.exception as? FirebaseAuthUserCollisionException
error?.let { handleMergeConflict(it) }
}
}
}
}
Output: Google Sign-In works reliably with proper result handling.
Prevention
- Add SHA-1 fingerprint in Firebase Console (both debug and release).
- Use the web client ID from
google-services.jsonforrequestIdToken(). - Use
registerForActivityResultinstead ofstartActivityForResult. - Handle
ApiExceptionstatus codes for troubleshooting.
Common Mistakes with Firebase auth google
- Using
foldlinstead offoldl'causing stack overflow on large lists - Forgetting
deriving (Show, Eq)on custom data types needed for debugging - Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
These mistakes appear frequently in real-world Android code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro