Search code examples
androidandroid-jetpack-composegoogle-signincredentialsandroid-credential-manager

Error on Google Sign In CredentialManager, using Jetpack Compose


I am trying to create a Sign In with Google Button but everytime credentialManager.getCredential is called, it gives me :

androidx.credentials.exceptions.NoCredentialException: During begin sign in, failure response from one tap: 10: Developer console is not set up correctly.

I tried resetting the SHA-1 Fingerprint, I've created both web application and android in the google cloud credential, I've used both the web app client id and android client id. I'm lost, please help


object DeveloperScreen{

    const val GOOGLE_WEB_CLIENT_ID = "xxxxxxxxxh5n94bxxxxxxxxxxx1.apps.googleusercontent.com"
//    const val GOOGLE_WEB_CLIENT_SECRET = "GxxxxxxxxCinwYDR8KQi3-wD9ugT311"
//    const val GOOGLE_ANDROID_CLIENT_ID = "3xxxxxxx80-7ja1n9nknxxxxxxxxxxxxxxxxxxxens33k.apps.googleusercontent.com"


    private suspend fun googleSignIn(context : Context) {


        val credentialManager = androidx.credentials.CredentialManager.create(context)

        val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
            .setFilterByAuthorizedAccounts(false)
            .setServerClientId(GOOGLE_WEB_CLIENT_ID)
            .build()

        Log.i("auth-google-googleIdOption", googleIdOption.toString())

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

        Log.i("auth-google-credentialRequest", request.toString())


        val result = credentialManager.getCredential(
            request = request,
            context = context,
        )

        Log.i("auth-google-result", result.toString())





    }



    @Composable
    public fun DeveloperScreen1(navController : NavHostController, context : Context){

        var phoneNumber by rememberSaveable { mutableStateOf("") }
        var email by rememberSaveable { mutableStateOf("")}
        var otpCode by rememberSaveable { mutableStateOf("") }

        var useEmail by rememberSaveable { mutableStateOf(false)}

        var message by rememberSaveable { mutableStateOf("")}

        val coroutineScope = rememberCoroutineScope()

        Column {


            var user : User? = getCurrentUser()

            Text(
                textAlign = TextAlign.Center,
                fontSize = 5.em,
                text = "DEV SCREEN",
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(top = 10.dp)

            )

            Text(
                text = message,
                color = Color.Black
            )

            Button(
                onClick = {

                    coroutineScope.launch {

                        googleSignIn(context)

                    }
...




var screenHeight = 0.dp
var screenWidth = 0.dp

var authViewModel = AuthViewModel()



class MainActivity : ComponentActivity() {



    @RequiresApi(Q)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)


        Log.d("Initialize", "App Started")

        setContent {


            var context: Context = LocalContext.current

            Box(
                Modifier
                    .background(color = Color(0xFFBDC6CA))
                    .safeDrawingPadding()
            ) {
                MetroFCTheme {
                    MainContent(context)



                }
            }
        }

        actionBar?.hide()
        WindowCompat.setDecorFitsSystemWindows(window, false)
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
            window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
        } else {
            window.insetsController?.apply {
//                hide(WindowInsetsAndroid.Type.statusBars())
                systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
            }
        }

    }


}



@RequiresApi(Q)
@Composable
fun MainContent(
    context : Context
){

    var user by remember{ mutableStateOf<User?>(null) }

    LaunchedEffect(key1 = user) {

        refreshMenu()

    }


    LaunchedEffect(key1 = "login") {

        user = loginAnonymously()
        Log.d("DB-User", "USER LOGIN SUCCESSFUL : $user")

    }


    Log.d("DB", "2." + user.toString())




    Log.d("Initialize","Database Connected")

    val configuration = LocalConfiguration.current
    screenHeight = configuration.screenHeightDp.dp
    screenWidth = configuration.screenWidthDp.dp

    var onDashboard by remember {mutableStateOf(true)}
    var onMenu = false
    val updateStates = { dashboard: Boolean, menu: Boolean ->
        onDashboard = dashboard
        onMenu = menu
    }

    val navController = rememberNavController()


    Scaffold(

        bottomBar = {
            if(authViewModel.isLoggedIn) NavigationBar(navController = navController, onDashboard, onMenu, updateStates)

                    },
        containerColor = MaterialTheme.colorScheme.background,
        contentWindowInsets = WindowInsets(0.dp),
        modifier = Modifier.fillMaxSize()

    ) {
    innerPadding ->

        val scrollState = rememberScrollState()

        val padding = innerPadding

        NavHost(
            navController = navController,
            startDestination = if (authViewModel.isLoggedIn) Route.DEV_SCREEN else Route.DEV_SCREEN,
            modifier = Modifier
//                .verticalScroll(state = scrollState)
                .fillMaxSize()
        ) {

            composable(route = Route.DEV_SCREEN){
                DeveloperScreen1(navController, context)
            }

            composable(route = Route.DASHBOARD_SCREEN) {

                authViewModel.login(user)
                DashboardScreen()
            }

            composable(route = Route.MENU_SCREEN) {
                authViewModel.login(user)
                MenuScreen(user)
            }
        }
    }
}

Process: com.metrofriedchicken.metrofc, PID: 20630 androidx.credentials.exceptions.NoCredentialException: During begin sign in, failure response from one tap: 10: Developer console is not set up correctly. at androidx.credentials.playservices.controllers.CredentialProviderBaseController$Companion.getCredentialExceptionTypeToException$credentials_play_services_auth_release(CredentialProviderBaseController.kt:110) at androidx.credentials.playservices.controllers.BeginSignIn.CredentialProviderBeginSignInController$resultReceiver$1$onReceiveResult$1.invoke(CredentialProviderBeginSignInController.kt:93)

I've tried :

  • Deleting Keystore and make a new one ( debug and release )
  • Used the web app client id and android client id
  • Change device
  • waited a day

Solution

  • I am assuming you are currently integrating the Credential Manager in debug mode and testing your integration in an app directly installed from Android Studio to your test device.

    In this case you will need to configure the SHA1 key currently being used to sign your app, which is Android Studio's debug keystore.

    In this case, you can get the SHA1 by running below command in Android Studio's terminal:

    ./gradlew signingreport

    enter image description here

    Copy the correct SHA1 fingerprint of correct Variant and Config from the terminal console and configure the same in cloud console for your app's Android OAuth2 client.

    In order to keep the steps cleaner, I am mentioning them as below:

    1. Create one Android OAuth2 client in cloud api console with you app's package name.
    2. Use the debug SHA1 key in this Android OAuth2 client creation as I mentioned above (in order to recognized this as debug client you can append the client name with debug as "your-app-debug")
    3. Create one Web OAuth2 client in cloud api console. This will act as the server for your app
    4. Copy the ClientID of this Web client and use in setServerClientId(ServerClientID) in your integration.

    With these simple steps alone, your integration should work fine.

    Optionally, as the next step,

    1. You can create another Android OAuth2 client with release key's SHA1 fingerprint for production, and for recognizing this client, can give it a name "Your-app-release"