29

I am trying to connect my users with my back end server , i used the example from the official google sign in plugin for flutter : https://pub.dartlang.org/packages/google_sign_in

the sign process goes fine and i get the username and email ect.. but i need the id Token to authenticate the user with my server.

Ps: Not using firebase , only google sign in.

Can anyone guide me how to get the id Token ?

kageeker
  • 447
  • 1
  • 5
  • 11

8 Answers8

51

You can try using this code:

_googleSignIn.signIn().then((result){
    result?.authentication.then((googleKey){
        print(googleKey.accessToken);
        print(googleKey.idToken);
        print(_googleSignIn.currentUser?.displayName);
    }).catchError((err){
        print('inner error');
    });
}).catchError((err){
    print('error occured');
});
user16217248
  • 3,119
  • 19
  • 19
  • 37
nonybrighto
  • 8,752
  • 5
  • 41
  • 55
6

The issue may be related to not using firebase. There is a google-services.json file which is given to you when you register your app in firebase, and you can use that with google_sign_in (this is the default way shown in the documentation).

I was getting null for the token value when trying to implement this without the google-services.json, but successfully signing into google.

If you don't want to use firebase, you have to jump through a couple hoops.

  • In google cloud console, register your app.
  • Then make sure you are 'in' your app that you just created in the top drop down menu.
  • in "apis and services" in the sidebar menu, go through the create Oauth consent screen menu, I don't remember having to fill out many fields, so leave them blank if you don't know what to put in.
  • then go to the "credentials" menu in the sidebar, and click "Create New Credentials", and select OAuth2 client ID. Make a web client, even though you're trying to use it with an android/ios app.
  • Make a file android/app/src/main/res/values/strings.xml
  • using the web client we just made, insert <?xml version="1.0" encoding="utf-8"?> <resources> <string name="default_web_client_id">YOUR WEB CLIENT ID</string> </resources> into the strings.xml file.
  • [edit] make one more client in the google console for android, and put in your local machine's sha1 key. This step is done for you automatically if you're using firebase. In this case, you have to create both the web client and one for your android device. In production, you'd be using a specific client for your production app.

That should do it I believe, might have missed a step.

I also wanted to verify on my backend that the incoming idtoken was valid, so I had to also make a service account (in the apis and services -> credentials page) and use that in my go server.

I'm still struggling to get this to work with ios, but the android side works great.

RonManning
  • 87
  • 1
  • 6
4

or try like this if id token was null, it worked for me.

As the docs point out you need oauth2 client id of your backend to request idToken or serverAuthCode.

from firebase google sigin in authentication copy the Web SDK configuration add paste in the following to res/values/strings.xml, That should work

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="default_web_client_id">{Web app Client id goes here}</string>
</resources>
giveJob
  • 1,500
  • 3
  • 17
  • 29
4

You can get access token and id token more simple like this:

final result = await _googleSignIn.signIn();
final ggAuth = await result.authentication;
print(ggAuth.idToken);
print(ggAuth.accessToken);

Or you also can add it to try-catch to handle an error.

try {
   final result = await _googleSignIn.signIn();
   final ggAuth = await result.authentication;
   print(ggAuth.idToken);
   print(ggAuth.accessToken);
} catch (error) {
  print(error);
}
icaksama
  • 712
  • 10
  • 15
3

I was struggling with this issue for about a month. Turns out I was getting the same access token, even when the user tried restarting the app. This was painful because my app dealt with scopes and in case a user misses to check one or more scopes in his first sign in, the app wouldn't work at all, even if he/she signs in again and gives the permissions.

Workaround which worked for me: I called the googleSignIn.currentUser.clearAuthCache() method followed by googleSignIn.signInSilently(). This returns a GoogleSignInAccount which can be used for further authentication. My guess is that the clearAuthCache() method clears the token cache and hence a new token is created. This should get you a new access token and let your app make valid calls.

I sincerely request Google developers to solve this issue. For now, this workaround is the only thing that worked.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Akshat J.
  • 103
  • 1
  • 6
3

One more clean way to achieve this:

late Map<String, dynamic> userObject = {};
var res = await _googleSignIn.signIn();
var googleKey = await res!.authentication;
userObject.addAll({
  'accessToken': googleKey.accessToken,
  'idToken': googleKey.idToken,
  'displayName': res.displayName ?? '',
  'email': res.email,
  'id': res.id,
  'avatarUrl': res.photoUrl ?? '',
  'serverAuthCode': res.serverAuthCode ?? '',
});
Smit Patel
  • 1,682
  • 18
  • 23
2

To retrieve the Is idToken worked for me:

1. The google-services.json file must be placed in /android/app/

2. you need to add to your /android/app/build.gradle

apply plugin: 'com.google.gms.google-services'

3. and to /android/build.gradle

classpath 'com.google.gms:google-services:4.3.4'

And that's it. GoogleSignIn will return a real idToken instead of null.

font: https://github.com/flutter/flutter/issues/12140#issuecomment-348720774

Diogo Souza
  • 298
  • 1
  • 3
  • 7
0

Try this:

When you create your GoogleSignIn object:

GoogleSignIn(
    clientId: "YOUR CLIENT ID"
  )

i hope it helps ;)

n4321d
  • 1,059
  • 2
  • 12
  • 31