androidfirebasefirebase-authenticationgoogle-signincredential-manager

Sign in with google into firebase using the new Credential Manager API


I'm learning Kotlin/Compose by making a to-do app with Firebase. Right now I'm trying to add Google sign-in. At first, I had been following a YouTube tutorial, but the API it was using turned out to be deprecated. I checked the official Firebase docs, but they are also outdated. So I'm trying to work it out on my own.

The deprecation message says I need to use Credential Manager. So far, I've managed to show the Google dialog and receive a GetCredentialResponse. The next step, I suppose, is to call Firebase.auth.signInWithCredential(<credentials>), but it needs an AuthCredential object, while I have a completely different type. There seems to be no way to create an AuthCredential object on my own - the initializer is package-private. What am I supposed to do?

My code

val googleIdOption = GetGoogleIdOption.Builder()
    .setAutoSelectEnabled(false)
    .setFilterByAuthorizedAccounts(false)
    .setServerClientId("...")
    .build()


val request = GetCredentialRequest.Builder()
    .addCredentialOption(googleIdOption)
    .build()

val result = try {
    credentialManager.getCredential(request = request, context = context)
} catch (e: Exception) {
    e.printStackTrace()
    if (e is kotlin.coroutines.cancellation.CancellationException) throw e
    null
}


val user = Firebase.auth.signInWithCredential(???).await()

Update: I found the GoogleAuthProvider.getCredential() method that creates an AuthCredential from the provided id token. Technically, I can now extract the idToken from the response bundle, but that would require manually parsing it. This seems wrong. Is there really no built in method?


Solution

  • Found the method that parses the credential response: GoogleIdTokenCredential.createFrom(result.credential.data).

    Full code:

    val credential = result?.credential
    val authCredential =
        if (credential is CustomCredential && credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
            val googleIdTokenCredential =
                GoogleIdTokenCredential.createFrom(credential.data)
    
            GoogleAuthProvider.getCredential(googleIdTokenCredential.idToken, null)
        } else {
            throw RuntimeException("Received an invalid credential type")
        }
    
    Firebase.auth.signInWithCredential(authCredential).await()