Search code examples
androidkotlingoogle-signingoogle-one-tap

Missing Feature{name=auth_api_credentials_begin_sign_in, version=7}


I use google One Tap Sign In and got following login failed message:

Missing Feature{name=auth_api_credentials_begin_sign_in, version=7}

I don't know what's wrong?

Always failed at:

.addOnFailureListener { beginSignInException ->
                        oneTapClient.beginSignIn(signUpRequest)
                            .addOnSuccessListener(
                                requireActivity()
                            ) { beginSignUpResult ->
                                IntentSenderRequest.Builder(beginSignUpResult.pendingIntent).build()
                                    .also { intentSenderRequest ->
                                        intentSenderRequestActivityResultLauncher.launch(
                                            intentSenderRequest
                                        )
                                    }
                            }
                            .addOnFailureListener { beginSignUpException ->
                                Log.d(
                                    TAG,
                                    "Google sign up failed:onResume: ${beginSignUpException.localizedMessage}"

                                )
                                Toast.makeText(
                                    requireContext(),
                                    "Google sign up failed:${beginSignUpException.localizedMessage}",
                                    Toast.LENGTH_SHORT
                                ).show()
                            }
                        Log.d(
                            TAG,
                            "Google sign in failed:onResume: ${beginSignInException.localizedMessage}"
                        )
                        Toast.makeText(
                            requireContext(),
                            "Google sign in failed:${beginSignInException.localizedMessage}",
                            Toast.LENGTH_SHORT
                        ).show()
                    }

Whole code:


private lateinit var signUpRequest: BeginSignInRequest
    private lateinit var signInRequest: BeginSignInRequest
    private lateinit var oneTapClient: SignInClient

private val intentSenderRequestActivityResultLauncher =
        registerForActivityResult(
            ActivityResultContracts.StartIntentSenderForResult()
        ) { result ->
            try {
                if (result.resultCode == Activity.RESULT_OK) {
                    result.data?.let { intent ->
                        oneTapClient.getSignInCredentialFromIntent(intent)
                    }?.also { signInCredential ->
                        val googleIdToken =
                            signInCredential.googleIdToken?.also { googleIdToken ->
                                Log.d(TAG, "googleIdToken: $googleIdToken")
                            }
                        val username = signInCredential.id
                        Log.d(TAG, "username: $username")
                        val password = signInCredential.password?.also { password ->
                            Log.d(TAG, "password: $password")
                        }
                        LoginFragmentDirections.actionLoginFragmentToMaintenanceFragment(
                            null,
                            signInCredential
                        ).also { navDirections ->
                            findNavController().navigate(navDirections)
                        }
                    }
                }
            } catch (e: ApiException) {
                when (e.statusCode) {
                    CommonStatusCodes.CANCELED -> {
                        Log.d(TAG, "One-tap dialog was closed.: ${e.message.toString()}")
                    }
                    CommonStatusCodes.NETWORK_ERROR -> {
                        Log.d(TAG, "One-tap encountered a network error.: ${e.message.toString()}")
                    }
                    else -> {
                        Log.d(TAG, "Couldn't get credential from result.: ${e.localizedMessage}")
                    }
                }
            }
        }


oneTapClient = Identity.getSignInClient(requireContext())
        signInRequest = BeginSignInRequest.builder()
            .setPasswordRequestOptions(
                BeginSignInRequest.PasswordRequestOptions.builder().setSupported(true).build()
            )
            .setGoogleIdTokenRequestOptions(
                BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
                    .setSupported(true)
                    .setServerClientId("")
                    .setFilterByAuthorizedAccounts(true)
                    .build()
            )
            .setAutoSelectEnabled(true)
            .build()
        signUpRequest = BeginSignInRequest.builder()
            .setGoogleIdTokenRequestOptions(
                BeginSignInRequest.GoogleIdTokenRequestOptions.builder().setSupported(true)
                    .setServerClientId("")
                    .setFilterByAuthorizedAccounts(false)
                    .build()
            ).build()





googleBtn.setOnClickListener {
                oneTapClient.beginSignIn(signInRequest)
                    .addOnSuccessListener(
                        requireActivity()
                    ) { beginSignInResult ->

                        IntentSenderRequest.Builder(beginSignInResult.pendingIntent).build()
                            .also { intentSenderRequest ->
                                intentSenderRequestActivityResultLauncher.launch(intentSenderRequest)
                            }
                    }
                    .addOnFailureListener { beginSignInException ->
                        oneTapClient.beginSignIn(signUpRequest)
                            .addOnSuccessListener(
                                requireActivity()
                            ) { beginSignUpResult ->
                                IntentSenderRequest.Builder(beginSignUpResult.pendingIntent).build()
                                    .also { intentSenderRequest ->
                                        intentSenderRequestActivityResultLauncher.launch(
                                            intentSenderRequest
                                        )
                                    }
                            }
                            .addOnFailureListener { beginSignUpException ->
                                Log.d(
                                    TAG,
                                    "Google sign up failed:onResume: ${beginSignUpException.localizedMessage}"

                                )
                                Toast.makeText(
                                    requireContext(),
                                    "Google sign up failed:${beginSignUpException.localizedMessage}",
                                    Toast.LENGTH_SHORT
                                ).show()
                            }
                        Log.d(
                            TAG,
                            "Google sign in failed:onResume: ${beginSignInException.localizedMessage}"
                        )
                        Toast.makeText(
                            requireContext(),
                            "Google sign in failed:${beginSignInException.localizedMessage}",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
            }

implementation 'com.google.android.gms:play-services-auth:20.4.0'

plugins {
    id 'com.android.application' version '7.3.1' apply false
    id 'com.android.library' version '7.3.1' apply false
    id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
    id 'com.google.dagger.hilt.android' version '2.44' apply false
}

Solution

  • https://developers.google.com/identity/sign-in/android/sign-in-identity

    After I changed to following code and changed setServerClientId() from mobile OAuth 2.0 client ID to web application OAuth 2.0 client ID.Then solve this problem. Can login logout successfully.

    googleBtn.setOnClickListener {
    
                    GetSignInIntentRequest.builder()
                        .setServerClientId(
                            "I changed this to google cloud web application OAuth 2.0 client ID")
                        .build().also { getSignInIntentRequest ->
    
                            Identity.getSignInClient(requireActivity())
                                .getSignInIntent(getSignInIntentRequest)
                                .addOnSuccessListener { pendingIntent ->
                                    IntentSenderRequest.Builder(pendingIntent.intentSender).build()
                                        .also { intentSenderRequest ->
                                            try {
                                                intentSenderRequestActivityResultLauncher.launch(
                                                    intentSenderRequest
                                                )
                                            } catch (e: ActivityNotFoundException) {
                                                Log.d(
                                                    TAG,
                                                    "addOnSuccessListener:Google Sign-in failed:$e "
                                                )
                                            }
                                        }
    
                                }
                                .addOnFailureListener { exception ->
                                    Log.d(TAG, "addOnFailureListener:Google Sign-in failed:$exception ")
                                }
                        }
    }
    
    private val intentSenderRequestActivityResultLauncher =
            registerForActivityResult(
                ActivityResultContracts.StartIntentSenderForResult()
            ) { result ->
                try {
                    if (result.resultCode == Activity.RESULT_OK) {
                        result.data?.let { intent ->
                            oneTapClient.getSignInCredentialFromIntent(intent)
                        }?.also { signInCredential ->
                            val googleIdToken =
                                signInCredential.googleIdToken?.also { googleIdToken ->
                                    Log.d(TAG, "googleIdToken: $googleIdToken")
                                }
                            val username = signInCredential.id
                            Log.d(TAG, "username: $username")
                            val password = signInCredential.password?.also { password ->
                                Log.d(TAG, "password: $password")
                            }
                            LoginFragmentDirections.actionLoginFragmentToMaintenanceFragment(
                                null,
                                signInCredential
                            ).also { navDirections ->
                                findNavController().navigate(navDirections)
                            }
                        }
                    }
                } catch (e: ApiException) {
                    when (e.statusCode) {
                        CommonStatusCodes.CANCELED -> {
                            Log.d(TAG, "One-tap dialog was closed.: ${e.message.toString()}")
                        }
                        CommonStatusCodes.NETWORK_ERROR -> {
                            Log.d(TAG, "One-tap encountered a network error.: ${e.message.toString()}")
                        }
                        else -> {
                            Log.d(TAG, "Couldn't get credential from result.: ${e.localizedMessage}")
                        }
                    }
                }
            }