5
votes

I currently try to implement google_sign_in package in Flutter (https://pub.dartlang.org/packages/google_sign_in).

For this, I followed the example of their repository (https://github.com/flutter/plugins/blob/master/packages/google_sign_in/lib/google_sign_in.dart).

In that example in "initState" is a call signInSilently.

@override
void initState() {
  super.initState();
  _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount account) {
    setState(() {
      _currentUser = account;
      loggedIn = true;
    });
  });
  loggedIn = false;
  _googleSignIn.signInSilently();
}

I tried this code in iOS. On my first App Start, it worked well. But since I logged out I get an error here all the time I restart my app.It is the following PlatformException:

PlatformException(sign_in_required, com.google.GIDSignIn, The operation couldn’t be completed. (com.google.GIDSignIn error -4.))

I found in question Google Sign-In Error -4 that the error code is because of a missing Auth in Keychain.

The solution while swift programming is to call the method * hasAuthInKeychain* before the try to signInSilently. My problem is that the GoogleSignIn class in the flutter package has no function named like this.

Is there another call I need to run with this package to be sure I can try a silent log in? Or am I doing something wrong to get this message or is there even the possibility of catching this error?

Edit

I tried Marcel's solution, too. Somehow it is not catching the PlatfromException.

I do not know if this will help: signInSilently() is calling a method in which there is a the following call (google_sign_in.dart, line 217):

await channel.invokeMethod(method)

In platform_channel.dart there is a call

codec.decodeEnvelope(result);

The platform exception gets thrown in here.

if (errorCode is String && (errorMessage == null || errorMessage is String) && !buffer.hasRemaining)
  throw PlatformException(code: errorCode, message: errorMessage, details: errorDetails);
else
  throw const FormatException('Invalid envelope');

Edit 2

Since I just run my app and not started it in debug mode it somehow works again without throwing an exception. I do not know how this affects the code and why I got this exception. I can also run the code in debug mode again.

Since then I had the exception once again. Again I restarted android studio and runned the application once without debug mode.

3
HI please look at this issue github.com/flutter/flutter/issues/15796 - a0x2
Which version of google_sign_in is yours? I have the same exactly piece of code running on both OS in an app of mine on version ^3.2.4 - Victor Hugo Montes
I notice that the error appear when user has logged off before and it happens only in emulator only. After compiled and bring to real device, there is no error occurred. CMIIW. - Samuel Surya

3 Answers

1
votes

You could just check if the sign in failed by handling the PlatformException like this:

void _setUpGoogleSignIn() async {
  try {
    final account = await _googleSignIn.signInSilently();
    print("Successfully signed in as ${account.displayName}.");
  } on PlatformException catch (e) {
    // User not signed in yet. Do something appropriate.
    print("The user is not signed in yet. Asking to sign in.");
    _googleSignIn.signIn();
  }
}
1
votes

This is one way to catch the error and run _googleSignIn.signIn();

GoogleSignInAccount googleSignInAccount = await googleSignIn
    .signInSilently(suppressErrors: false)
    .catchError((dynamic error) async {
  GoogleSignInAccount googleSignInAccount =
      await _googleSignIn.signIn();
});
1
votes

In my case, I did not want the user to see the login window automatically. In this case I changed from signIn to signOut. This way, I send the user to another view with an explanatory message and a login button.

GoogleSignInAccount googleSignInAccount = await googleSignIn
    .signInSilently(suppressErrors: false)
    .catchError((dynamic error) async {
      GoogleSignInAccount googleSignInAccount = await _googleSignIn.signOut();
      return googleSignInAccount;
    });