27

I followed below steps as this link

  1. I downloaded google-services.json to my app folder.
  2. My project level gradle file :

    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
        classpath 'com.google.gms:google-services:1.5.0-beta2'
    }
    
  3. My app level gradle file :

    apply plugin: 'com.android.application'
    apply plugin: 'com.google.gms.google-services'
    
    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        compile 'com.google.android.gms:play-services-identity:8.3.0'
        compile 'com.google.android.gms:play-services:8.3.0'
        compile 'com.google.android.gms:play-services-plus:8.3.0'
        compile 'com.google.android.gms:play-services-auth:8.3.0'
        ...
    }
    
  4. I created OAuth 2.0 client ID for my backend server and pass this Client ID to strings.xml file.

  5. And finally I created GoogleSignInOptions and GoogleApiClient objects as below :

    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestIdToken(getString(R.string.server_client_id))
            .build();
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();
    

    But the problem is result.isSuccess() always returns false in handleSignInResult function. I'm thinking maybe I'm doing somethings wrongly in 1th or 2nd step. And my codes are almost similar to this SignInActivity.java. Any help would be appreciated.

melomg
  • 737
  • 3
  • 20
  • 39
  • IdToken I think it's https://github.com/googlesamples/google-services/blob/master/android/signin/app/src/main/java/com/google/samples/quickstart/signin/IdTokenActivity.java – BNK Dec 06 '15 at 10:18
  • I did same things, it is valid client server id but in onActivityResult function result.isSuccess() returns false again. – melomg Dec 07 '15 at 10:58
  • The `OAuth 2.0 client ID` you got, is its Type `Web application` or `Android`? – BNK Dec 08 '15 at 01:33
  • 1
    I suggest you read my answer at http://stackoverflow.com/questions/34099208/google-sign-in-idtoken/34146759#34146759, hope it helps! – BNK Dec 08 '15 at 02:07
  • Sorry I'm new in Google apis. I have to create web application type OAuth 2.0 client ID to get idToken in Android, right? and then we should also change the client id in google-services.json file which Google created for me for Android type according to this new client id? – melomg Dec 08 '15 at 08:42
  • 1
    Don't update `google-services.json` :) – BNK Dec 08 '15 at 08:55
  • It still returns false :( I uploaded my signup activity class to Bitbucket you can examine it from [this link](https://bitbucket.org/melomg/signinforidtoken/src) – melomg Dec 08 '15 at 09:57
  • 1
    I changed the OAuth 2.0 client IDs Web application Name making it different than my Android Client Id name when creating credentials. It is working now thanks to you. – melomg Dec 08 '15 at 11:33
  • Could you please help me with my issue, i spend some days trying to solve it... I use the same code, but finally when i retrive tokenId from google api, i get a String tokenId = <857 chars>... ?? If i tryed to validate it https://www.googleapis.com/oauth2/v3/tokeninfo?access_token= <857 chars response> i all the get 'error_description": "Invalid Value' ... How are you make a validation of your response? Are you also get String tokenId = <857 chars>? – Sirop4ik Aug 09 '16 at 07:54
  • @AlekseyTimoshchenko as @BNK said If your server needs to access other Google APIs you need to use the server auth code flow as far as I know. I was able to get refresh token with `refreshToken = res.getRefreshToken();` in case if you are wondering how i get [GoogleTokenResponse](https://developers.google.com/api-client-library/java/google-api-java-client/reference/1.19.1/com/google/api/client/googleapis/auth/oauth2/GoogleTokenResponse) you can look at [my question](http://stackoverflow.com/questions/36788395/how-can-i-reach-users-calendar-information-on-server) – melomg Sep 23 '16 at 18:07
  • @melomg thanks! i ask you a question below you answer under the providing link – Sirop4ik Sep 23 '16 at 18:27

4 Answers4

50

As I have answered at the following question:

Google Sign-In requestIdToken returns null

In order to request Id Token sucessfully, you should use a "Web application" type Client Id, instead of "Android" type Client Id.

You also find at Google's documentation, the following info (please note #3):

Create an OAuth 2.0 client ID for your backend server

If your app authenticates with a backend server or accesses Google APIs from your backend server, you must create an OAuth 2.0 client ID for your server. To create an OAuth 2.0 client ID:

  1. Open the Credentials page.
  2. Click Add credentials > OAuth 2.0 client ID.
  3. Select Web application.
  4. Click Create.

Pass this client ID to the requestIdToken or requestServerAuthCode method when you create the GoogleSignInOptions object.


Update Mar 26:

Android Developers Blog - Registering OAuth clients for Google Sign-In

Community
  • 1
  • 1
BNK
  • 23,994
  • 8
  • 77
  • 87
  • is this access token? – neobie Jun 29 '16 at 08:46
  • 1
    @neobie it's a token for backend authentication, please read at http://android-developers.blogspot.com/2016/03/registering-oauth-clients-for-google.html, however, I have not ever tried with `GoogleIdTokenVerifier`, which you will find more info at http://android-developers.blogspot.com/2016/01/using-google-sign-in-with-your-server.html. About the access token to access Google APIs, also at that link, you will find another link to http://android-developers.blogspot.com/2016/02/using-credentials-between-your-server.html – BNK Jun 29 '16 at 09:06
  • 1
    @neobie Another good link is https://developers.google.com/identity/sign-in/android/migration-guide#migrate_to_the_id_token_flow, please pay attention to `If all you need is the user's ID, email address, name, or profile picture URL, use the ID token flow.` and `If your server needs to access other Google APIs, such as Google Drive, Youtube, or Contacts, use the server auth code flow.`, there you will find 2 other links with some sample codes – BNK Jun 29 '16 at 09:26
  • Can I just use auth code for general purpose? I have figure out how to use auth code in backend PHP, but not yet for ID token. And if there is sample code that would be much better. – neobie Aug 05 '16 at 16:28
  • @neobie sorry I don't understand what `general purpose` here means. Moreover, I am not familiar with PHP so cannot help you with sample code, I think you can search more in SO :) – BNK Aug 06 '16 at 06:10
  • i mean use Auth Code instead of ID token to get user's ID, email address, name, or profile picture URL without using other Google APIs. – neobie Aug 06 '16 at 06:33
  • @neobie I don't think it can be, you can read more at https://developers.google.com/identity/sign-in/android/migration-guide#migrate_to_the_id_token_flow they have told when to choose which flow. However, you can search more – BNK Aug 06 '16 at 07:33
  • Could you please help me with my issue, i spend some days trying to solve it... I use the same code, but finally when i retrive tokenId from google api, i get a String tokenId = <857 chars>... ?? If i tryed to validate it https://www.googleapis.com/oauth2/v3/tokeninfo?access_token= <857 chars response> i all the get 'error_description": "Invalid Value' ... How are you make a validation of your response? Are you also get String tokenId = <857 chars>? – Sirop4ik Aug 09 '16 at 07:54
  • @AlekseyTimoshchenko at present I have no testing environment to check, however, I think you should use `access token` instead of `ID token`, about the example how to get the `access token` please read my answer at http://stackoverflow.com/questions/33998335/how-to-get-access-token-after-user-is-signed-in-from-gmail-in-android to see if it can help you or not. Another good link I think you can also read https://developers.google.com/identity/sign-in/android/migration-guide#migrate_to_the_id_token_flow as I commented above – BNK Aug 09 '16 at 08:07
  • 1
    You saved my life. Thank you @BNK – user3734429 Aug 21 '16 at 21:12
  • I used web client id as well as android id, none of them worked, I debugged it, the gs variable is null in the GoogleSignInAccount object, everything else has some value. Please help.. – Ari Oct 25 '16 at 11:44
  • @Ari, IMO you should check your code as well as Google's guide. Or you can create a new question about your issue in S.O – BNK Oct 26 '16 at 01:39
  • 1
    It's fine, I checked out the documentation and realized my mistake. Thanks anyways.. – Ari Oct 26 '16 at 10:29
21

In my case i had previously,

 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();

I fixed it by adding adding the requestToken method,

 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestIdToken(getString(R.string.default_web_client_id))
            .build();

Now its working for me.Hopefully this can help somebody having issues like me.

yubaraj poudel
  • 3,821
  • 1
  • 31
  • 28
  • I had the same issue and this fixed it. Does this fix work fine on release apk as well? – wick.ed Jul 11 '17 at 16:44
  • 1
    yeah it works. But for release don't forget to put your release sha1 key. – yubaraj poudel Jul 12 '17 at 05:54
  • in the google api console right? I update that in the api console. Do I have to put release sha in the code as well? – wick.ed Jul 12 '17 at 17:13
  • 1
    Yeah, if you are using firebase then while creating the project or simply add your release sha1 key.@wick.ed – yubaraj poudel Jul 13 '17 at 08:32
  • The same issue I am facing right now, it's been two days now, I have published my app to google play store but now I want to remove signup and simply add google sign in but it gave me error, what sha1 key should I use while implementing it debug or release? And where I will specify this key? I am using release sha1 key in firebase. – M Umer Sep 28 '19 at 17:00
2

We can use the requestServerAuthCode method with the "WebApplication ClientID" and create a method to fetch the access token as below;

 new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)

                    .requestServerAuthCode("WEBAPPLICATION CLIENT ID")

                    .requestEmail()

                    .build())

As seen we need a WEBAPPLICATION CLIENT ID we can be obtained from https://console.developers.google.com;

obtain web application client id as follows

void fetchGoogleAuthToken(){

    OkHttpClient okHttpclient = new OkHttpClient();
    RequestBody requestBody = new FormEncodingBuilder()
            .add("grant_type", "authorization_code")
            .add("client_id", "812741506391-
              h38jh0j4fv0ce1krdkiq0hfvt6n5amrf.apps.googleusercontent.com")
            .add("client_secret", "{clientSecret}")
            .add("redirect_uri","")
            .add("code", "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8")
            .build();

    final Request request = new Request.Builder()
            .url("https://www.googleapis.com/oauth2/v4/token")
            .post(requestBody)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(final Request request, final IOException e) {
            Log.e(LOG_TAG, e.toString());                
        }

        @Override
        public void onResponse(Response response) throws IOException {
            try {
                JSONObject jsonObject = new 
                             JSONObject(response.body().string());
                final String message = jsonObject.toString(5);
                Log.i(LOG_TAG, message);                    
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    });
}

Please use compile 'com.squareup.okhttp:okhttp:2.6.0' (ver 3-RC1 will have different classes) or you can use any network framework to make the above call

With a successful response, you will have the following info in log-cat:

I/onResponse: {
          "expires_in": 3600,

          "token_type": "Bearer",

          "refresh_token": "1\/xz1eb0XU3....nxoALEVQ",

          "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjQxMWY1Ym......yWVsUA",

     **"access_token": "ya29.bQKKYah-........_tkt980_qAGIo9yeWEG4"**
     }

as it is seen the acces_token is available for further use.

Subhrajyoti Sen
  • 1,525
  • 14
  • 18
0

I was facing the same issue. All I did was simply download the google-services.json file again, replaced the old one and it worked. Don't know why this happened, my guess is something changed, And before Overwriting I forgot to compare.

Doilio Matsinhe
  • 2,131
  • 16
  • 29