Google Sign-In With Flutter: Error Code -4

4,923

Solution 1

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

Solution 2

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

Solution 3

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();
  }
}
Share:
4,923
Sonius
Author by

Sonius

Updated on December 08, 2022

Comments

  • Sonius
    Sonius over 1 year

    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.

  • Sonius
    Sonius over 5 years
    tried that one. But somehow it is not catching the error. In google sign in is a "await channel.invokeMethod(method). In there the PlatformException is been thrown.
  • Marcel
    Marcel over 5 years
    Okay, I edited the code to an explicit try-catch. Does that work?