Search code examples
androidgoogle-apigoogle-signingoogle-photos

Getting list of Google Photos returned 401 unauthenticated


I'm working on an app that has the capability to display images from Google Photos.

Problem

The problem happened when the user manually revoke my app inside the Gmail Permission. After the user does this(revoke permission), open the app again and when the app is trying to access the list of images from Google Photos, this is the error that I received in JSON.

{
  "error": {
    "code": 401,
    "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "status": "UNAUTHENTICATED"
  }
}

What I did after that is I sign out and revoke from Google Sign In. I Sign In again, the pop up to select Gmail account appeared but Grant app permission popup did not appear. It supposed to appear so that the app can ask the user to allow permission again.

Grant app permission popup. enter image description here

Here is how I do Google Sign In

val googleSignInOptions =
    GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestScopes(Scope("https://www.googleapis.com/auth/photoslibrary.readonly"))
        .requestEmail()
        .build()
val googleSignInClient = GoogleSignIn.getClient(context, googleSignInOptions!!)

Here is how I sign out and revoke in code

googleSignInClient?.signOut()
    ?.addOnCompleteListener {
        //Sign Out Complete
        googleSignInClient?.revokeAccess()?.addOnCompleteListener {
            //Revoke Complete
        }
    }

My observations

  1. Even though permission has already been revoked in Gmail Permission page, GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(context), Scope(GOOGLE_PHOTOS_READ_SCOPE)) still return true. Logically it should return false because the user already revoked the permission.
  2. Even though the app already signs out from Google Sign In, when the user signs in again, the user will get same access token as the previous one provided that the expiration time is still within 1 hour.

End of the day, I would like to be able to show Grant app permission pop up even though after the user manually revoke the permission. Thank you.


Solution

  • I have found a solution to this problem.

    When logout, I need to clear the token by calling this function in a thread.

    GoogleAuthUtil.clearToken(
        context,
        token
    )
    

    As overall, this is how I sign out.

    googleSignInClient.signOut()
        .addOnCompleteListener {
            if (it.isSuccessful) {
                thread {
                    GoogleAuthUtil.clearToken(
                        context,
                        token
                    )
                    googleSignInClient.revokeAccess()
                }
            }
            callBack(it.isSuccessful)
        }