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
}
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}")
}
}
}
}