# How to sign-in with Google using Firebase Auth in Jetpack Compose

> A Jetpack Compose tutorial that teaches you how to use Firebase Auth with Jetpack Compose to authenticate via Facebook using the LoginButton or custom UI.

Published 26 July 2022 by Alex Styl.

[Firebase Authentication](https://firebase.google.com/docs/auth/android/start) heavily relies on [Activity's onActivityResult()](<https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int)>) mechanism. As your composables can live on any .kt file outside of your `Activity` we do not have access to that callback anymore.

This tutorial showcases how to make use of `rememberLauncherForActivityResult` and a suggested way to use Firebase Auth library in your Jetpack Compose app.

## Add the Firebase Auth dependency in your Android project

In this tutorial we are going to use the Firebase Authentication library dependency and plug-in.

We are also going to use [Jetbrain's kotlinx-coroutines-play-services](https://github.com/Kotlin/kotlinx.coroutines/tree/master/integration/kotlinx-coroutines-play-services) library. This allow us to wait for Firebase Tasks to complete without requiring an `Activity`.

## Add the Play Services gradle plugin

In your `/build.gradle` file, include the Play Services dependencies in your `buildscript`:

```gradle
buildscript {
    dependencies {
        // other dependencies

        classpath 'com.google.gms:google-services:4.3.13'
    }
}
```

In your `app/build.gradle` file, make use of the plugin:

```gradle
plugins {
    // other plugins
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'

    id 'com.google.gms.google-services'
}
```

Make sure to include your `google-services.json` file in your `/app` module folder:

![Download google-services.json. Switch to the Project view in Android Studio to see your project root directory. Move the google-services.json into your Android app module root directory.](https://composables.com/blog-assets/static/images/google-services-location.png)

### Include your apps SHA certificate fingerprints in the Firebase Console

It is important to include your application's _SHA certificate fingerprints_ in your Firebase Project, otherwise the sign in will always fail.

If you are releasing your app to the Google Play Store you will need to generate and publish an App Bundle. As Google is the one singing your app via the Google Play Store, you can find the keys in the Google Play Store console.

However, if you are generating an APK, you can find the keys on your local machine.

### Where to find the SHA key for your an App Bundle

Open the [Google Play Console](https://play.google.com/console) and select the app you want to add sign in to.

From the left side menu Go to **Release -> Setup -> App Integrity**

![Where to find the app integrity option in the Google Console](https://composables.com/blog-assets/static/images/app-integrity-menu.png)

Click on the 'App Signin' tab and copy the `SHA1` value and paste it in your [Firebase project's project settings](https://console.firebase.google.com/project).

### Where to find the SHA key for your APK

Go to your project's terminal in Android Studio (or navigate to your project's root directory via your favorite terminal) and type `./gradlew signingreport`

The command will print the SHA certificate fingerprints of different build variants of your project.

Copy the `SHA1` value of the `debug` variant

![./gradlew singing report](https://composables.com/blog-assets/static/images/signinreport.png)

and paste them in your [Firebase project's project settings](https://console.firebase.google.com/project).

![Firebase SSH Fingerprints](https://composables.com/blog-assets/static/images/firebase-ssh-fingerprints.png)

if you are releasing the app to the Play Store, do the same for the `release` variant.

### Add the required dependencies

In your `app/build.gradle` file, add the following dependencies:

```kotlin
implementation platform('com.google.firebase:firebase-bom:30.3.0')
implementation 'com.google.firebase:firebase-auth-ktx'

implementation('org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.3')
```

## Build the UI

Our UI will display a _SIGN IN_ button when the user is not signed in. When the user is signed in, we will greet them with their account's name and we will display a button to sign them out.

In order to know whether the user is signed in or not, we will use `FirebaseUser` as our UI state. A `null` value represent that the user is not signed in:

```kotlin
var user by remember { mutableStateOf(Firebase.auth.currentUser) }
Column {
    if (user == null) {
        Text("Not logged in")
        Button(onClick = {
            // TODO start sign in
        }) {
            Text("Sign in via Google")
        }
    } else {
        Text("Welcome ${user!!.displayName}")
        Button(onClick = {
            // TODO sign out
        }) {
            Text("Sign out")
        }
    }
}
```

## Authenticate via Google

The Firebase Auth library relies on the `Activity`'s `startActivityForResult()` mechanism to perform the sign in. We are going to use the `ActivityResultContracts` API instead as it is the respective Jetpack Compose counterpart.

The following snippet shows how to create our own version of a `launcher` to wrap the steps required by Firebase to Sign in.

```kotlin
@Composable
fun rememberFirebaseAuthLauncher(
    onAuthComplete: (AuthResult) -> Unit,
    onAuthError: (ApiException) -> Unit
): ManagedActivityResultLauncher<Intent, ActivityResult> {
    val scope = rememberCoroutineScope()
    return rememberLauncherForActivityResult(StartActivityForResult()) { result ->
        val task = GoogleSignIn.getSignedInAccountFromIntent(result.data)
        try {
            val account = task.getResult(ApiException::class.java)!!
            val credential = GoogleAuthProvider.getCredential(account.idToken!!, null)
            scope.launch {
                val authResult = Firebase.auth.signInWithCredential(credential).await()
                onAuthComplete(authResult)
            }
        } catch (e: ApiException) {
            onAuthError(e)
        }
    }
}
```

All is left now is to use the launcher to perform the sign in:

```kotlin
var user by remember { mutableStateOf(Firebase.auth.currentUser) }
val launcher = rememberFirebaseAuthLauncher(
    onAuthComplete = { result ->
        user = result.user
    },
    onAuthError = {
        user = null
    }
)
val token = stringResource(R.string.default_web_client_id)
val context = LocalContext.current
Column {
    if (user == null) {
        Text("Not logged in")
        Button(onClick = {
            val gso =
                GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestIdToken(token)
                    .requestEmail()
                    .build()
            val googleSignInClient = GoogleSignIn.getClient(context, gso)
            launcher.launch(googleSignInClient.signInIntent)
        }) {
            Text("Sign in via Google")
        }
    } else {
        Text("Welcome ${user!!.displayName}")
        Button(onClick = {
            Firebase.auth.signOut()
            user = null
        }) {
            Text("Sign out")
        }
    }
}
```

Congratulations. You have just used Firebase Authentication using Jetpack Compose. 👏

## Checkout the Sample on Github

Check out the repository on Github and try it out on your machine: https://github.com/alexstyl/firebase-auth-tutorial
