1. Avant de commencer
Découvrez comment implémenter Se connecter avec Google sur Android à l'aide du Gestionnaire d'identifiants.
Prérequis
- Connaissances de base de Kotlin pour le développement Android.
- Connaissances de base de Jetpack Compose (en savoir plus).
Points abordés
- Créer un projet Google Cloud et des clients OAuth.
- Implémenter le flux de connexion Bottom Sheet.
- Implémenter le flux de connexion explicite par bouton.
Ce dont vous avez besoin
- Android Studio installé.
- Un ordinateur répondant à la configuration système requise pour Android Studio et l'émulateur.
- Java Development Kit (JDK) installé.
2. Créer un projet Android Studio
Pour commencer, créez un projet dans Android Studio :
- Ouvrez Android Studio, puis cliquez sur New Project (Nouveau projet).

- Sélectionnez Phone and Tablet > Empty Activity (Téléphone et tablette > Activité vide), puis cliquez sur Next (Suivant).

- Configurez les paramètres du projet :
- Name (Nom) : choisissez un nom de projet.
- Package name (Nom du package) : utilisez le nom par défaut ou choisissez le vôtre.
- Minimum SDK (SDK minimal) : sélectionnez la dernière version stable ou > Android 14.

- Cliquez sur Finish (Terminer) et attendez la fin de la compilation initiale du projet.

3. Configurer votre projet Google Cloud
Créer un projet Google Cloud
- Accédez à la console Google Cloud, puis sélectionnez ou créez un projet.

- Accédez à API et services > Écran de consentement OAuth.

- Cliquez sur Get started (Commencer), puis remplissez les champs obligatoires :
- App Name (Nom de l'application) : utilisez le nom de votre application Android.
- User Support Email (Adresse e-mail d'assistance utilisateur) : sélectionnez votre compte Google.
- Audience : sélectionnez External (Externe).
- Contact Info (Informations de contact) : saisissez votre adresse e-mail.

- Consultez le Règlement sur les données utilisateur dans les services d'API Google, puis cliquez sur Create (Créer).

Configurer des clients OAuth
Vous devez créer un client Web et un client Android dans la console Google Cloud pour obtenir les ID client pour l'authentification.
- Client Android : sécurise les requêtes en validant le nom du package et la signature SHA-1 de votre application.
- Client Web : agit en tant que client de backend pour le service de connexion Google.
Créer un client OAuth 2.0 Android
- Sur la page Clients, cliquez sur Create Client (Créer un client), puis sélectionnez Android comme Application type (Type d'application).

- Saisissez le nom du package de votre application (correspondant à la ligne 1 de votre fichier
MainActivity.kt). - Générez votre signature SHA-1. Ouvrez le terminal Android Studio et exécutez la commande suivante :macOS/Linux :
Windows:keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
keytool -list -v -keystore "C:\Users\USERNAME\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
- Copiez l'empreinte SHA-1 à partir du résultat de la commande, collez-la dans le champ SHA-1 fingerprint (Empreinte SHA-1) de la console, puis cliquez sur Create (Créer).

Créer un client OAuth 2.0 Web
- Cliquez à nouveau sur Create Client (Créer un client), puis sélectionnez Web Application (Application Web) comme Application type (Type d'application).
- Nommez votre client Web, laissez les champs URL/Origines vides, puis cliquez sur Create.

- Copiez l'ID client généré à partir de la boîte de dialogue de confirmation. Vous l'utiliserez dans votre code Kotlin.

4. Configurer un appareil virtuel Android
Pour tester l'application, vous pouvez utiliser un appareil Android physique ou un appareil virtuel Android (AVD).
Créer et exécuter l'AVD
- Dans Android Studio, ouvrez le Gestionnaire d'appareils, cliquez sur Create Virtual Device (Créer un appareil virtuel) (ou sur l'icône +), puis sélectionnez Medium Phone (Téléphone moyen).
- Sélectionnez la dernière version stable comme image système, puis cliquez sur Finish (Terminer).
- Lancez l'émulateur en cliquant sur l'icône Lecture/Exécuter à côté de l'appareil.

Se connecter à un compte Google sur l'appareil
- Sur l'émulateur, ouvrez l'application Settings (Paramètres), puis accédez à Google.
- Cliquez sur Sign in to your Google Account (Se connecter à votre compte Google), puis suivez les instructions.

5. Ajouter des dépendances
Ajoutez les bibliothèques requises pour l'authentification et l'intégration de l'ID Google à votre projet :
- Accédez à File > Project Structure > Dependencies > app (Fichier > Structure du projet > Dépendances > app).
- Cliquez sur + > Library Dependency (Dépendance de la bibliothèque), recherchez
com.google.android.libraries.identity.googleid:googleid, puis sélectionnez la dernière version (par exemple,1.1.1). - Cliquez à nouveau sur + > Library Dependency (Dépendance de la bibliothèque), recherchez
play-services-auth, puis sélectionnez la bibliothèque avec l'ID de groupecom.google.android.gms. - Cliquez sur OK pour appliquer les modifications et synchroniser votre projet.

6. Implémenter le flux Bottom Sheet

Le flux Bottom Sheet exploite l'API Credential Manager pour permettre aux utilisateurs de se connecter à votre application à l'aide de leur compte Google sur Android de manière simplifiée. Conçu pour être rapide et pratique, en particulier pour les utilisateurs réguliers, ce flux doit être déclenché au lancement de l'application.
Créer la requête de connexion
- Pour commencer, ouvrez
MainActivity.kt, puis supprimez les fonctions par défautGreeting()etGreetingPreview(). - Ajoutez les instructions d'importation suivantes après celles existantes à partir de la ligne 3 :
import android.content.Context import android.os.Build import android.util.Log import android.widget.Toast import androidx.annotation.RequiresApi import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.credentials.CredentialManager import androidx.credentials.CustomCredential import androidx.credentials.GetCredentialRequest import androidx.credentials.exceptions.GetCredentialCancellationException import androidx.credentials.exceptions.GetCredentialCustomException import androidx.credentials.exceptions.GetCredentialException import androidx.credentials.exceptions.NoCredentialException import com.google.android.libraries.identity.googleid.GetGoogleIdOption import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential import com.google.android.libraries.identity.googleid.GoogleIdTokenParsingException import java.security.SecureRandom import java.util.Base64 import kotlinx.coroutines.delay import kotlinx.coroutines.launch const val TAG = "MainActivity" - Ajoutez cette fonction composable sous la classe
MainActivitydans votre fichierMainActivity.kt:@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @Composable fun BottomSheet(webClientId: String) { val context = LocalContext.current // LaunchedEffect is used to run a suspend function when the composable is first launched. LaunchedEffect(Unit) { // Create a Google ID option with filtering by authorized accounts enabled. val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder() .setFilterByAuthorizedAccounts(true) .setServerClientId(webClientId) .setNonce(generateSecureRandomNonce()) .build() // Create a credential request with the Google ID option. val request: GetCredentialRequest = GetCredentialRequest.Builder() .addCredentialOption(googleIdOption) .build() // Attempt to sign in with the created request using an authorized account val e = signIn(request, context) // If the sign-in fails with NoCredentialException, there are no authorized accounts. // In this case, we attempt to sign in again with filtering disabled. if (e is NoCredentialException) { val googleIdOptionFalse: GetGoogleIdOption = GetGoogleIdOption.Builder() .setFilterByAuthorizedAccounts(false) .setServerClientId(webClientId) .setNonce(generateSecureRandomNonce()) .build() val requestFalse: GetCredentialRequest = GetCredentialRequest.Builder() .addCredentialOption(googleIdOptionFalse) .build() //We will build out this function in a moment signIn(requestFalse, context) } } } //This function is used to generate a secure nonce to pass in with our request fun generateSecureRandomNonce(byteLength: Int = 32): String { val randomBytes = ByteArray(byteLength) SecureRandom.getInstanceStrong().nextBytes(randomBytes) return Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes) }
Analyse du code
LaunchedEffect(Unit): déclenche le flux de connexion immédiatement lorsque le composable s'affiche pour la première fois.GetGoogleIdOption.Builder(): configure la requête de jeton d'ID Google.setFilterByAuthorizedAccounts(true): tente d'abord une connexion silencieuse en filtrant les comptes que l'utilisateur a déjà autorisés pour cette application, ce qui réduit les frictions pour les utilisateurs réguliers.setNonce(...): transmet un nonce aléatoire sécurisé généré pour chaque requête pargenerateSecureRandomNonce()afin d'empêcher les attaques par rejeu.
signIn(request, context): exécute la requête. Si l'exécution échoue avec une exceptionNoCredentialException(ce qui signifie qu'aucun compte précédemment autorisé n'existe), le flux revient àsetFilterByAuthorizedAccounts(false)pour permettre à l'utilisateur de sélectionner n'importe quel compte Google connecté sur l'appareil.
Envoyer la requête de connexion
Une fois la requête de connexion créée, vous pouvez utiliser le Gestionnaire d'identifiants pour terminer le processus de connexion. Créez une fonction appelée signIn qui exécute la requête et gère les exceptions courantes qui peuvent se produire.
Ajoutez cette fonction sous la fonction BottomSheet dans votre fichier MainActivity.kt :
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
suspend fun signIn(request: GetCredentialRequest, context: Context): Exception? {
val credentialManager = CredentialManager.create(context)
val failureMessage = "Sign in failed!"
//using delay() here helps prevent NoCredentialException when the BottomSheet Flow is triggered
//on the initial running of our app
delay(250)
return try {
// The getCredential is called to request a credential from Credential Manager.
val result = credentialManager.getCredential(
request = request,
context = context,
)
Log.i(TAG, result.toString())
val credential = result.credential
if (credential is CustomCredential &&
credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
Log.i(TAG, "Signed in as: ${googleIdTokenCredential.id}")
}
Toast.makeText(context, "Sign in successful!", Toast.LENGTH_SHORT).show()
Log.i(TAG, "(☞゚ヮ゚)☞ Sign in Successful! ☜(゚ヮ゚☜)")
null
} catch (e: GoogleIdTokenParsingException) {
Toast.makeText(context, failureMessage, Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": Issue with parsing received GoogleIdToken", e)
e
} catch (e: NoCredentialException) {
Toast.makeText(context, failureMessage, Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": No credentials found", e)
e
} catch (e: GetCredentialCancellationException) {
Toast.makeText(context, "Sign-in cancelled", Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": Sign-in was cancelled", e)
e
} catch (e: GetCredentialCustomException) {
Toast.makeText(context, failureMessage, Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": Issue with custom credential request", e)
e
} catch (e: GetCredentialException) {
Toast.makeText(context, failureMessage, Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": Failure getting credentials", e)
e
}
}
Analyse du code
credentialManager.getCredential(...): appelle l'API Credential Manager pour afficher la bottom sheet ou la boîte de dialogue du sélecteur de compte système.delay(250): met en pause brièvement pour éviter une condition de concurrence lorsque la bottom sheet est déclenchée immédiatement au démarrage de l'application avant que le service Credential Manager n'ait terminé l'initialisation.- Gestion des exceptions : capture et enregistre les erreurs d'identifiants courantes (par exemple, annulation, identifiants manquants ou problèmes d'analyse de jeton) et fournit des commentaires aux utilisateurs à l'aide de toasts.
Déclencher le flux Bottom Sheet
Modifiez votre classe MainActivity pour appeler BottomSheet() au démarrage. Remplacez YOUR_CLIENT_ID_HERE par l'ID client de votre application Web :
class MainActivity : ComponentActivity() {
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//replace with your own web client ID from Google Cloud Console
val webClientId = "YOUR_CLIENT_ID_HERE"
setContent {
//ExampleTheme - this is derived from the name of the project not any added library
//e.g. if this project was named "Testing" it would be generated as TestingTheme
ExampleTheme {
Surface(
modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background,
) {
//This will trigger on launch
BottomSheet(webClientId)
}
}
}
}
}
Enregistrez votre projet (File > Save), puis exécutez l'application :
- Appuyez sur le bouton d'exécution :

- Lorsque l'application se lance sur l'émulateur, la bottom sheet de connexion doit s'afficher. Cliquez sur Continue (Continuer) pour tester le flux.

- Une notification toast doit s'afficher pour confirmer que la connexion a réussi.

7. Implémenter le flux par bouton

Le flux par bouton offre aux utilisateurs une option explicite pour se connecter ou s'inscrire. L'utilisation d'une image de marque standard garantit une expérience cohérente. Utilisez des composants pré-approuvés qui respectent les Consignes relatives à la marque Se connecter avec Google.
Ajouter l'icône de la marque
- Téléchargez les composants de la marque ici, puis extrayez le fichier ZIP.
- Copiez
signin-assets/Android/png@2x/neutral/android_neutral_sq_SI@2x.png. - Dans Android Studio, collez le fichier dans votre dossier res > drawable, renommez-le
siwg_button.png, puis cliquez sur OK.
Code du flux par bouton
Ce flux réutilise la même fonction d'assistance signIn, mais transmet une GetSignInWithGoogleOption au lieu de GetGoogleIdOption. Contrairement au flux Bottom Sheet, le flux par bouton explicite ne préfiltre pas ni n'invite automatiquement à utiliser des identifiants ou des clés d'accès stockés. Collez cette fonction composable sous la fonction BottomSheet :
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@Composable
fun ButtonUI(webClientId: String) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
val onClick: () -> Unit = {
val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption
.Builder(serverClientId = webClientId)
.setNonce(generateSecureRandomNonce())
.build()
val request: GetCredentialRequest = GetCredentialRequest.Builder()
.addCredentialOption(signInWithGoogleOption)
.build()
coroutineScope.launch {
signIn(request, context)
}
}
Image(
painter = painterResource(id = R.drawable.siwg_button),
contentDescription = "",
modifier = Modifier
.fillMaxSize()
.clickable(enabled = true, onClick = onClick)
)
}
Analyse du code
GetSignInWithGoogleOption: contrairement au flux Bottom Sheet, le flux par bouton explicite utilise cette option pour inviter les utilisateurs à sélectionner leur compte Google sans filtrage automatique.coroutineScope.launch: lance une coroutine pour exécuter la fonctionsignInsuspendue de manière asynchrone lorsque l'utilisateur clique sur le bouton.Image: affiche le drawablesiwg_buttonde la marque et associe un écouteur de clics pour déclencher le flux.
Ajouter le bouton à la mise en page d'interface utilisateur
Modifiez votre mise en page MainActivity pour afficher à la fois le BottomSheet automatique et le ButtonUI explicite alignés verticalement :
class MainActivity : ComponentActivity() {
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//replace with your own web client ID from Google Cloud Console
val webClientId = "YOUR_CLIENT_ID_HERE"
setContent {
//ExampleTheme - this is derived from the name of the project not any added library
//e.g. if this project was named "Testing" it would be generated as TestingTheme
ExampleTheme {
Surface(
modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background,
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
//This will trigger on launch
BottomSheet(webClientId)
//This requires the user to press the button
ButtonUI(webClientId)
}
}
}
}
}
}
Tester le flux par bouton
- Exécutez l'application.
- Fermez la bottom sheet initiale en cliquant en dehors de la zone de la feuille.
- Cliquez sur le bouton Se connecter avec Google pour lancer la boîte de dialogue de connexion, puis sélectionnez votre compte.

- Vérifiez le résultat : consultez Logcat pour confirmer l'impression de votre nom d'utilisateur/adresse e-mail.
8. Conclusion
Félicitations ! Vous avez implémenté Se connecter avec Google à l'aide du Gestionnaire d'identifiants Android.
Ressources supplémentaires
- Documentation du Gestionnaire d'identifiants Android
- Guide de dépannage du Gestionnaire d'identifiants
- FAQ sur Credential Manager
- Assistance Stack Overflow
Code complet de MainActivity.kt
Voici le code complet de MainActivity.kt à titre de référence :
package com.example.example
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.example.example.ui.theme.ExampleTheme
import android.content.ContentValues.TAG
import android.content.Context
import android.util.Log
import android.widget.Toast
import androidx.credentials.exceptions.GetCredentialException
import androidx.compose.foundation.clickable
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.credentials.CredentialManager
import androidx.credentials.exceptions.GetCredentialCancellationException
import androidx.credentials.exceptions.GetCredentialCustomException
import androidx.credentials.exceptions.NoCredentialException
import androidx.credentials.GetCredentialRequest
import com.google.android.libraries.identity.googleid.GetGoogleIdOption
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
import com.google.android.libraries.identity.googleid.GoogleIdTokenParsingException
import java.security.SecureRandom
import java.util.Base64
import kotlinx.coroutines.CoroutineScope
import androidx.compose.runtime.LaunchedEffect
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//replace with your own web client ID from Google Cloud Console
val webClientId = "YOUR_CLIENT_ID_HERE"
setContent {
//ExampleTheme - this is derived from the name of the project not any added library
//e.g. if this project was named "Testing" it would be generated as TestingTheme
ExampleTheme {
Surface(
modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background,
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
//This will trigger on launch
BottomSheet(webClientId)
//This requires the user to press the button
ButtonUI(webClientId)
}
}
}
}
}
}
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@Composable
fun BottomSheet(webClientId: String) {
val context = LocalContext.current
// LaunchedEffect is used to run a suspend function when the composable is first launched.
LaunchedEffect(Unit) {
// Create a Google ID option with filtering by authorized accounts enabled.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(true)
.setServerClientId(webClientId)
.setNonce(generateSecureRandomNonce())
.build()
// Create a credential request with the Google ID option.
val request: GetCredentialRequest = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
// Attempt to sign in with the created request using an authorized account
val e = signIn(request, context)
// If the sign-in fails with NoCredentialException, there are no authorized accounts.
// In this case, we attempt to sign in again with filtering disabled.
if (e is NoCredentialException) {
val googleIdOptionFalse: GetGoogleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false)
.setServerClientId(webClientId)
.setNonce(generateSecureRandomNonce())
.build()
val requestFalse: GetCredentialRequest = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOptionFalse)
.build()
signIn(requestFalse, context)
}
}
}
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@Composable
fun ButtonUI(webClientId: String) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
val onClick: () -> Unit = {
val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption
.Builder(serverClientId = webClientId)
.setNonce(generateSecureRandomNonce())
.build()
val request: GetCredentialRequest = GetCredentialRequest.Builder()
.addCredentialOption(signInWithGoogleOption)
.build()
coroutineScope.launch {
signIn(request, context)
}
}
Image(
painter = painterResource(id = R.drawable.siwg_button),
contentDescription = "",
modifier = Modifier
.fillMaxSize()
.clickable(onClick = onClick)
)
}
fun generateSecureRandomNonce(byteLength: Int = 32): String {
val randomBytes = ByteArray(byteLength)
SecureRandom.getInstanceStrong().nextBytes(randomBytes)
return Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes)
}
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
suspend fun signIn(request: GetCredentialRequest, context: Context): Exception? {
val credentialManager = CredentialManager.create(context)
val failureMessage = "Sign in failed!"
//using delay() here helps prevent NoCredentialException when the BottomSheet Flow is triggered
//on the initial running of our app
delay(250)
return try {
// The getCredential is called to request a credential from Credential Manager.
val result = credentialManager.getCredential(
request = request,
context = context,
)
Log.i(TAG, result.toString())
val credential = result.credential
if (credential is CustomCredential &&
credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
Log.i(TAG, "Signed in as: ${googleIdTokenCredential.id}")
}
Toast.makeText(context, "Sign in successful!", Toast.LENGTH_SHORT).show()
Log.i(TAG, "(☞゚ヮ゚)☞ Sign in Successful! ☜(゚ヮ゚☜)")
null
} catch (e: GoogleIdTokenParsingException) {
Toast.makeText(context, failureMessage, Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": Issue with parsing received GoogleIdToken", e)
e
} catch (e: NoCredentialException) {
Toast.makeText(context, failureMessage, Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": No credentials found", e)
e
} catch (e: GetCredentialCancellationException) {
Toast.makeText(context, "Sign-in cancelled", Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": Sign-in was cancelled", e)
e
} catch (e: GetCredentialCustomException) {
Toast.makeText(context, failureMessage, Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": Issue with custom credential request", e)
e
} catch (e: GetCredentialException) {
Toast.makeText(context, failureMessage, Toast.LENGTH_SHORT).show()
Log.e(TAG, failureMessage + ": Failure getting credentials", e)
e
}
}