Google signIn tokenId is invalid_token - android

I need to get google+ signIn tokenId.
Here is my code:
var mGSO = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(WEB_CLIENT_ID)//from developer console
.requestEmail()
.build()
mGoogleApiClient = GoogleApiClient.Builder(mActivity)
.enableAutoManage(mActivity, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, mGSO)
.build()
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
var tokenId = result.signInAccount.idToken
}
So I successfully get tokenId, but when I try to check it here (https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=) I receive message:
{
"error": "invalid_token",
"error_description": "Invalid Value"
}
Token the same every time I try to get it!
What is happening?
Any idea how to fix this?
UPDATE
found this issue: https://github.com/PhilipGarnero/django-rest-framework-social-oauth2/issues/61
I was using the wrong google token from my sign-in on iOS. I
originally used user.authentication.idToken which is wrong, and will
not work.
The correct token is user.authentication.accessToken.
but i cant find any similar accessToken at GoogleSignInResult object....
UPDATE 2
i am using debug apk.
here is my button click code:
fun onGooglePlusClicked(v: View) {
val signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient)
mActivity?.startActivityForResult(signInIntent, GOOGLE_SIGN_IN)
}

Very important thing
Google needs to update the documentation, because it is misleading.
Either you are on iOS, or Android, you have to send the accessToken to the backend and not the idToken
You can get the accessToken from user object (e.g. val accessToken = user.authentication.accessToken)
For example, if you want to get user info, try this GET request:
https://www.googleapis.com/oauth2/v3/tokeninfo?access_token={access_token}

The answer was founded here:
https://developers.google.com/identity/protocols/CrossClientAuth
key words: GoogleAuthUtil.getToken()
so, here is my updated code:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
Observable.create(Observable.OnSubscribe<String> {
var **accessTokent** = GoogleAuthUtil.getToken(mActivity!!, result.signInAccount.account, "oauth2:" + Scopes.PLUS_LOGIN)
//send token to server
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe()
}
hope this will help someone :)

Answer in 2021:
I've had the same problem.
For me clearing app data completely solved the issue.
Seemed like an old expired token got stuck.
Also the id token should be verified here
https://oauth2.googleapis.com/tokeninfo?id_token=

In my case, I was testing this in Unity and I copied the idToken value that I printed in logcat. Turns out, there is some character or size limit (1024 bytes?) for a line in either adb logcat or Unity's Debug.Log() method. So the printed token value was getting truncated. What I did then for testing was that I copied the token value to clipboard during runtime and then checked again with the tokeninfo endpoint https://oauth2.googleapis.com/tokeninfo?id_token= and it was accepted.

Related

Exception while trying to access Google Fit API - The user must be signed in to make this API call

I am trying to set up a wearable app (for Huawei Watch 2) running on WearOS to provide a sort of continous feed of Heart Rate (BPM) into a Google Fit account, which is read into another smarphone application.
The issue comes when I am trying to set up the account and access the data as it follows:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BODY_SENSORS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.BODY_SENSORS),GOOGLE_FIT_PERMISSIONS_REQUEST_CODE)
}
fitnessOptions = FitnessOptions.builder()
.addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_READ)
.addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_WRITE)
.build()
account = GoogleSignIn.getAccountForExtension(this, fitnessOptions)
if (!GoogleSignIn.hasPermissions(account, fitnessOptions)) {
GoogleSignIn.requestPermissions(
this, // your activity
GOOGLE_FIT_PERMISSIONS_REQUEST_CODE, // e.g. 1
account,
fitnessOptions);
} else {
accessGoogleFit()
}
timer.scheduleAtFixedRate(
object : TimerTask() {
override fun run() {
Log.i("[TimerTask]", "Retrieving data..")
accessGoogleFit()
Log.i("[Account]", "" + account.email)
}
},0, 1000
)
// Enables Always-on
setAmbientEnabled()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (resultCode) {
Activity.RESULT_OK -> when (requestCode) {
GOOGLE_FIT_PERMISSIONS_REQUEST_CODE -> accessGoogleFit()
else -> {}
}
else -> {}
}
}
private fun accessGoogleFit() {
val cal: Calendar = Calendar.getInstance()
val now = Date()
cal.setTime(now)
val endTime: Long = cal.getTimeInMillis()
cal.add(Calendar.DAY_OF_MONTH, -1)
val startTime: Long = cal.getTimeInMillis()
val historyRequest = DataReadRequest.Builder()
.read(DataType.TYPE_HEART_RATE_BPM)
.enableServerQueries()
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build()
val sourceRequest = DataSourcesRequest.Builder()
.setDataTypes(DataType.TYPE_HEART_RATE_BPM)
.setDataSourceTypes(DataSource.TYPE_RAW, DataSource.TYPE_DERIVED)
.build()
Fitness.getHistoryClient(this,account)
.readData(historyRequest)
.addOnSuccessListener{
response-> txt_GoogleFit_FitData.setText(response.dataSets.get(0).toString())
}
.addOnFailureListener{ e ->
Log.e("[GoogleFIT]", "Find data sources request failed", e)
}
Fitness.getSensorsClient(this, account)
.findDataSources(sourceRequest)
.addOnSuccessListener { dataSources ->
dataSources.forEach {
Log.i("[GoogleFIT]", "Data source found: ${it.streamIdentifier}")
Log.i("[GoogleFIT]", "Data Source type: ${it.dataType.name}")
if (it.dataType == DataType.TYPE_HEART_RATE_BPM) {
Log.i("[GoogleFIT]", "Data source for LOCATION_SAMPLE found!")
}
}
}
.addOnFailureListener { e ->
Log.e("[GoogleFIT]", "Find data sources request failed", e)
}
}
Stack trace of exception:
2021-01-27 17:08:07.032 13743-13767/com.example.watch_bpmupdated2 I/[TimerTask]: Retrieving data..
2021-01-27 17:08:07.036 13743-13767/com.example.watch_bpmupdated2 I/[Account]: <<default account>>
2021-01-27 17:08:07.057 13743-13743/com.example.watch_bpmupdated2 E/[GoogleFIT]: Find data sources request failed
com.google.android.gms.common.api.ApiException: 4: The user must be signed in to make this API call.
at com.google.android.gms.common.internal.ApiExceptionUtil.fromStatus(com.google.android.gms:play-services-base##17.1.0:4)
at com.google.android.gms.common.internal.zai.zaf(com.google.android.gms:play-services-base##17.1.0:2)
at com.google.android.gms.common.internal.zak.onComplete(com.google.android.gms:play-services-base##17.1.0:6)
at com.google.android.gms.common.api.internal.BasePendingResult.zaa(com.google.android.gms:play-services-base##17.1.0:176)
at com.google.android.gms.common.api.internal.BasePendingResult.setResult(com.google.android.gms:play-services-base##17.1.0:135)
at com.google.android.gms.common.api.internal.BaseImplementation$ApiMethodImpl.setFailedResult(com.google.android.gms:play-services-base##17.1.0:29)
at com.google.android.gms.common.api.internal.zad.zaa(com.google.android.gms:play-services-base##17.1.0:9)
at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.zac(com.google.android.gms:play-services-base##17.1.0:175)
at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.onConnectionFailed(com.google.android.gms:play-services-base##17.1.0:79)
at com.google.android.gms.common.internal.zag.onConnectionFailed(com.google.android.gms:play-services-base##17.1.0:2)
at com.google.android.gms.common.internal.BaseGmsClient$zzg.zza(com.google.android.gms:play-services-basement##17.1.1:6)
at com.google.android.gms.common.internal.BaseGmsClient$zza.zza(com.google.android.gms:play-services-basement##17.1.1:25)
at com.google.android.gms.common.internal.BaseGmsClient$zzb.zzo(com.google.android.gms:play-services-basement##17.1.1:11)
at com.google.android.gms.common.internal.BaseGmsClient$zzc.handleMessage(com.google.android.gms:play-services-basement##17.1.1:49)
at android.os.Handler.dispatchMessage(Handler.java:105)
at com.google.android.gms.internal.common.zzi.dispatchMessage(com.google.android.gms:play-services-basement##17.1.1:8)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
2021-01-27 17:08:07.060 13743-13743/com.example.watch_bpmupdated2 E/[GoogleFIT]: Find data sources request failed
com.google.android.gms.common.api.ApiException: 4: The user must be signed in to make this API call.
at com.google.android.gms.common.internal.ApiExceptionUtil.fromStatus(com.google.android.gms:play-services-base##17.1.0:4)
at com.google.android.gms.common.internal.zai.zaf(com.google.android.gms:play-services-base##17.1.0:2)
at com.google.android.gms.common.internal.zak.onComplete(com.google.android.gms:play-services-base##17.1.0:6)
at com.google.android.gms.common.api.internal.BasePendingResult.zaa(com.google.android.gms:play-services-base##17.1.0:176)
at com.google.android.gms.common.api.internal.BasePendingResult.setResult(com.google.android.gms:play-services-base##17.1.0:135)
at com.google.android.gms.common.api.internal.BaseImplementation$ApiMethodImpl.setFailedResult(com.google.android.gms:play-services-base##17.1.0:29)
at com.google.android.gms.common.api.internal.zad.zaa(com.google.android.gms:play-services-base##17.1.0:9)
at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.zac(com.google.android.gms:play-services-base##17.1.0:175)
at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.onConnectionFailed(com.google.android.gms:play-services-base##17.1.0:79)
at com.google.android.gms.common.internal.zag.onConnectionFailed(com.google.android.gms:play-services-base##17.1.0:2)
at com.google.android.gms.common.internal.BaseGmsClient$zzg.zza(com.google.android.gms:play-services-basement##17.1.1:6)
at com.google.android.gms.common.internal.BaseGmsClient$zza.zza(com.google.android.gms:play-services-basement##17.1.1:25)
at com.google.android.gms.common.internal.BaseGmsClient$zzb.zzo(com.google.android.gms:play-services-basement##17.1.1:11)
at com.google.android.gms.common.internal.BaseGmsClient$zzc.handleMessage(com.google.android.gms:play-services-basement##17.1.1:49)
at android.os.Handler.dispatchMessage(Handler.java:105)
at com.google.android.gms.internal.common.zzi.dispatchMessage(com.google.android.gms:play-services-basement##17.1.1:8)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
My watch is paired to the smartphone I am using to read the data (I just need faster updates from google fit, and thought about forcing this. Code not available here for that).
The same google fit account is present, logged into Google Fit app and synced on both devices.
Everything runs smoothly on the smartphone (even with the same code), while on the Watch I get the "user must be signed in" exception when setting up the account.
Google services dependencies, application permissions are set the same way on both devices, as well as the required OAuth settings, SHA1 and credentials on the developer console.
Could this be an issue related to the watch->App->Google Fit account synchronization, or am I missing something?
Register the project in the Google Console and add your Google Account as a test user after adding the OAuth 2.0 Client ID for your project.
This should fix the login issue.
Here is how I fixed it:
Verify that you have a test user in Google Cloud with your Email
Verify that you have a OAuth 2.0 Client IDs on Google Cloud Credentials linked with your certificate
Verify that your app certificate on Android using an app like Package Manager correspond to the written above
Make sure that you call GoogleSignIn.hasPermissions before trying to access anything else and that it returns true
Theses checked should fix most errors from Google Fit not giving you any results or keeping you on the loading screen
Also, Google Fit historical requests need to have a good TimeUnit ex for Type_WEIGHT TimeUnit should be MILLISECONDS as any higher will not return any values
ex historical request builder:
DataReadRequest.Builder()
.read(DataType.TYPE_WEIGHT)
.setTimeRange(/* 1st January 2013 */, /* now */, TimeUnut.MILLISECONDS)
.build()

How to implement google sign in

I implemented the google sign in api in my android app. Everything was fine until recently. One of the challenges I had was with client_id which regenerated. The most recent that has opened more errors is that the google sign in wont work in the release.apk that built.
After two days of debugging I decided to create a new demo project to start the process afresh. It won't work as the task return false for task.isSuccessful.
Perhaps there is something I am missing.
const val RC_SIGN_IN = 0
class MainActivity : AppCompatActivity() {
lateinit var observer:StartActivityForResults
private lateinit var mGoogleSignInClient:GoogleSignInClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
observer = StartActivityForResults(activityResultRegistry)
lifecycle.addObserver(observer)
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build()
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
sign_in_button.setOnClickListener{
signIn()
}
}
private fun signIn() {
val signInIntent = mGoogleSignInClient.signInIntent
startActivityForResult(signInIntent, RC_SIGN_IN)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
// The Task returned from this call is always completed, no need to attach
// a listener.
val task = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
task?.isSuccess
Toast.makeText(this, "Success", Toast.LENGTH_LONG).show()
}
else{
Log.i("title", "OKCODE ${Activity.RESULT_OK} RESULTCODE ${resultCode}")
}
}
}
Easily add sign-in to your Android app with FirebaseUI
If you haven't already, add Firebase to your Android project.
Add the dependencies for FirebaseUI to your app-level build.gradle file
dependencies {
// ...
implementation 'com.firebaseui:firebase-ui-auth:6.2.0'
}
In the Firebase console, open the Authentication section and enable the sign-in methods you want to support. Some sign-in methods require additional information, usually available in the service's developer console.
If you support Google Sign-in and haven't yet specified your app's SHA-1 fingerprint, do so from the Settings page of the Firebase console
// Choose authentication providers
val providers = arrayListOf(
AuthUI.IdpConfig.EmailBuilder().build(),
AuthUI.IdpConfig.PhoneBuilder().build(),
AuthUI.IdpConfig.GoogleBuilder().build(),
AuthUI.IdpConfig.FacebookBuilder().build(),
AuthUI.IdpConfig.TwitterBuilder().build())
// Create and launch sign-in intent
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.build(),
RC_SIGN_IN)
When the sign-in flow is complete, you will receive the result in onActivityResult:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN) {
val response = IdpResponse.fromResultIntent(data)
if (resultCode == Activity.RESULT_OK) {
// Successfully signed in
val user = FirebaseAuth.getInstance().currentUser
// ...
} else {
// Sign in failed. If response is null the user canceled the
// sign-in flow using the back button. Otherwise check
// response.getError().getErrorCode() and handle the error.
// ...
}
}
}
Not sure if this answers your question, but I faced a similar issue where signing worked in debug builds and wouldn't work for release builds.
In the Firebase console, if you have Google Sign in enabled you will be prompted to enter the SHA-1 Key of your build. Now, what happened in my case was I got the SHA-1 key for debug keystore and didn't do it for the release key-store.
Try,
keytool -list -v
-alias -keystore <path-to-production-keystore
and entering it on your Firebase console.

How to add onCompleteListener when signing in with Firebase Auth pre-built UI?

I am using prebuilt Firebase UI to authenticate user such as below:
val providers = arrayListOf(
AuthUI.IdpConfig.EmailBuilder().build(),
AuthUI.IdpConfig.GoogleBuilder().build())
startActivityForResult(
AuthUI.getInstance().createSignInIntentBuilder()
.setAvailableProviders(providers)
.build(),
RC_SIGN_IN)
How do I attach a OnCompleteListener during sign-in? More specifically, I want to call getAdditionalUserInfo().isNewUser() to check if the user is first time log in. I know I can add onCompleteListener if I sign in using email and password-based method, but I want to handle multiple sign-in providers using the prebuilt UI method above.
In onActivityResult you receive the result for the sign in with some data passed as Parcelable which u are already overriding for validation!
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN) {
// this class has all the needed data !
val response = IdpResponse.fromResultIntent(data)
if (resultCode == Activity.RESULT_OK) {
// Successfully signed in
val isNewUser = response?.isNewUser!! // flag to check if the user is first time login
}
}
}
#See class IdpResponse of package com.firebase.ui.auth:-
Dug a bit deep for you ;) Happy coding!

Get Google Refresh token from existing user auth code

I'm trying to get the Google Refresh token, the thing is that i haven't seen my current scenario anywhere, what i'm trying to accomplish is get the refresh token from a user auth token already generated by a google sign in from a native android app, basically i request every google permission i need on the app, and the the auth code from the sign in, with that auth code i send it to my Firebase functions backend, there i try to get the refresh token but i always get invalid_grant from google, so i don't know where could i be messing up
I saw that requesting oauth offline may solve the problem, but i'm sign in in the android app, so i cannot make a sign in request offline from the backend, i need the sign in and authentication to be only on the android app and i need this to make Google assistant requests over the backend and for this, the only thing missing is the refresh token
I have my google oauth2 key from google cloud console and the client initialized
var OAuth2 = google.auth.OAuth2;
var _client_id = require('./config/secrets/omni.json').installed.client_id;
var _client_secret = require('./config/secrets/omni.json').installed.client_secret;
var redirect = require('./config/secrets/omni.json').installed.redirect_uris[1];
return new OAuth2(
_client_id,
_client_secret,
redirect
);
And finally try to get the token:
function getRefreshToken(authCode, idFBUser) {
return new Promise((resolve, reject) => {
getOAuthClient().getToken(authCode, function(err, token) {
if (!err) {
console.log(`Get Token success, token: ${token}`);
getOAuthClient().setCredentials(token);
saveRefreshFirebase(idFBUser, token)
resolve(token);
} else {
console.log("Get Token error", err);
reject(err);
}
});
});
}
the error i'm getting exactly is this one: { error: 'invalid_grant', error_description: 'Bad Request' }
The method i use in the android app to request the auth code is this one:
Creating the GoogleSignIn instance
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.requestId()
.requestIdToken(getClientId())
.requestServerAuthCode(getClientId())
.requestScopes(ASSISTANT_SCOPE)
.build()
googleSignInClient = GoogleSignIn.getClient(this, gso)
Calling the Sign in Intent:
val signInIntent = googleSignInClient.signInIntent
startActivityForResult(signInIntent, RESULT_GOOGLE_SIGNIN)
Handle the Sign in Result:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
RESULT_GOOGLE_SIGNIN -> {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
try {
task.result?.let { account ->
val id = account.id
val idToken = account.idToken
val authCode = account.serverAuthCode
Log.d("GoogleSignIn", "ID: $id")
Log.d("GoogleSignIn", "ID Token: $idToken")
Log.d("GoogleSignIn", "Auth code: $authCode")
btnLogin.text = "Sign Out"
loggedIn = true
} ?: Log.e("GoogleSignIn", "Exception: ${task.exception}")
} catch (e: Exception) {
Log.e("GoogleSignIn", "Catch Exception: $e")
}
}
}
}
}
and the authCode is the one i used to try to get the Refresh Token in the backend
You need to call
.requestServerAuthCode(getClientId(),true)
instead of
.requestServerAuthCode(getClientId())
If you want to get a refresh token. The javascript code you posted works with refresh tokens.
This is the easiest way to authenticate your app because all other kinds of token will expire. Refresh tokens dont expire. The Google Sign in library gives you an access code which you are already using to obtain a refresh token. You need to save this refresh token and send it to Google in order to obtain access tokens. The access token can then finally be used to make API requests.
By the way, that is actually what 'offline access' refers to. Took me a while to figure this out as well.

GoogleSignInClient return 8 (internal error)

I'm trying to connect my game to Google Play Games Services, but when I try to login, it always returns me an error code 8 (internal error).
The code is copy pasted from Google example:
lateinit var signInClient: GoogleSignInClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_settings)
settings_login.setOnClickListener { login() }
signInClient = GoogleSignIn.getClient(this,
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).build()
)
}
private fun login() {
startActivityForResult(signInClient.signInIntent, 9001)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode != 9001) {
return
}
val task = GoogleSignIn.getSignedInAccountFromIntent(intent)
try {
val account = task.getResult(ApiException::class.java)
onConnected(account)
} catch (apiException: ApiException) {
var message: String? = apiException.message
if (message == null || message.isEmpty()) {
message = getString(R.string.signin_other_error)
}
onDisconnected()
AlertDialog.Builder(this)
.setMessage(message)
.setNeutralButton(android.R.string.ok, null)
.show()
}
}
In Google Play Console I've linked my game with debug keystore SHA-1.
I've checked everythin mentioned in Troubleshooting guide, but I still get this message again and again.
Does someone faced this issue? Any ideas how to debug it?
EDIT:
I found that it actually logs me in - if I restart game, method signInSilently() will be successful. However, it still shows this error 8 when I logout and try to log in manually. Could it be the problem with login activity overlay?
Oh, and I checked api access in Google Play Api Console - it shows that api actually receives my calls and it doesn't mention any errors.
EDIT 2: I've added requestEmail() to GoogleSignInOptions.Builder, and it shows me overlay with access request. However, it still fails in GoogleSignIn.getSignedInAccountFromIntent(intent).getResult(ApiException::class.java) with same error (8 - internal error).
It looks like this bug in Google Play Services 12.2.21:
https://github.com/googlesamples/google-services/issues/358
Google is supposed to be working on a fix for release over the air soon..
it's maybe late but I found the reason. It fixed in my case and I see your code has same problem.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
...
val task = GoogleSignIn.getSignedInAccountFromIntent(intent)
...
}
The intent you passed to the method getSignedInAccountFromIntent() is not the intent that returned by onActivityResult. The intent you passed come from activity, so you need to change it to
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
"data" is the intent returned by onActivityResult
I didn't found the reason of this error, but I found an (ugly) workaround. I noticed, that when I restart game after manual login, even if there was this error, signInSilently() method works fine, which means that API actually authenticate me and fails later. So in catch block I'm checking for status code of error, and, if it's (8 - internal error), I'm requesting last signed in account. If account is present, I assume user to be logged in.
It's really dirty but I'm out of ideas.
//onActivityResult
val task = GoogleSignIn.getSignedInAccountFromIntent(intent)
try {
val account = task.getResult(ApiException::class.java)
onSuccess(account)
} catch (apiException: ApiException) {
val acc = GoogleSignIn.getLastSignedInAccount(context)
if (apiException.statusCode == 8 && acc != null && acc.email != null) {
onSuccess(account)
} else {
onFail(apiException)
}
}
I have a client with that error. Only ONE! With a Galaxy S9. Nothing happens when clicking on the Sign In button (startActivityForResult -> GoogleSignIn.getClient.getSignInIntent)

Categories

Resources