Google Sign-In With Flutter: Error Code -4

Viewed 5853

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 Answers

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();
  }
}

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();
});

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;
    });
Related