Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canceling Google Sign In cause an exception in Flutter

I am trying to implement Google Sign In in my android flutter app, but I have this problem:

When user cancel Google sign in (tap on back button) this exception is throw.

PlatformException (PlatformException(sign_in_canceled, com.google.android.gms.common.api.ApiException: 12501: , null))

I found that from some newer version this should be fixed and it should return null instead of an exception. Currently I am using google_sign_in: ^4.1.1

I tried to wrap my code inside try-catch block or using .catchError() on the method, but nothing help.

My code looks like this:

  Future googleSign(BuildContext context) async {
    final GoogleSignInAccount googleSignInAccount =
        await googleSignIn.signIn().catchError((onError) => print(onError));

    final GoogleSignInAuthentication googleSignInAuthentication =
        await googleSignInAccount.authentication;

    final AuthCredential credential = GoogleAuthProvider.getCredential(
      accessToken: googleSignInAuthentication.accessToken,
      idToken: googleSignInAuthentication.idToken,
    );

    final AuthResult authResult = await _auth.signInWithCredential(credential);

    return authResult.user.uid;
  }

Do you have any idea, how to handle this exception? Thanks.

like image 348
Petr Jelínek Avatar asked Jan 02 '20 10:01

Petr Jelínek


People also ask

How to solve flutter and Google_Sign_in plugin?

to solve Flutter and google_sign_in plugin: PlatformException (sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null) Generate SHA1 and SHA256 keys. Add both the SHA1 and SHA256 to firebase. (in you app settings) Download google-services.json to android/app in your project folder.

How to authenticate a Google client in flutter?

Also Read This Google’s Official Method to Authenticating Your Client. Generate SHA1 and SHA256 keys. Download google-services.json to android/app in your project folder. In your terminal run the command flutter clean . Run your flutter app.

What is the error code for sign in failure in flutter?

I/flutter ( 9795): PlatformException(sign_in_failed, Status{statusCode=ERROR, resolution=null}, null) This makes it hard to differentiate request cancellation from a generic sign in failure, for the purpose of showing a retry snackbar / dialog for example. Using google_sign_in 3.0.6 Steps to Reproduce

Is it possible to cancel the sign-in process on Android?

However, cancelling the sign-in on android currently throws a Platform Exception containing... According to the comments on the signIn() function in google_sign_in.dart, if the user cancels the sign in process, then null should be returned. However, cancelling the sign-in on android currentl... Skip to content Sign up Product


1 Answers

The issue seems to be caused by an inability of the Dart VM to correctly detect exceptions that are caught with catchError() as explained in this StackOverflow question

There doesn't seem to be a perfect fix to this bug. However, I came across a somewhat good workaround on Github.

It requires you to edit package:flutter/src/services/platform_channel.dart.

You would have to wrap this 👇🏽

final Map<dynamic, dynamic> result = await invokeMethod<Map<dynamic, dynamic>>(method, arguments);
return result?.cast<K, V>();

with a try/catch block as follows 👇🏽 (found at the beginning of invokeMapMethod)

try {
    final Map<dynamic, dynamic> result = await invokeMethod<Map<dynamic, dynamic>>(method, arguments);
    return result?.cast<K, V>();
} on PlatformException catch (err) { // Checks for type PlatformException
    if (err.code == 'sign_in_canceled') { // Checks for sign_in_canceled exception
        print(err.toString());
    } else {
        throw err; // Throws PlatformException again because it wasn't the one we wanted
    }
}

You might also want to check if googleSignInAccount is null in which case, you should return return null to prevent further exceptions like NoSuchMethodError: The getter 'authentication' was called on null

So, your code can be re-written as

...

final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn().catchError((onError) => print(onError));

// Return null to prevent further exceptions if googleSignInAccount is null
if (googleSignInAccount == null) return null;

final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication;

...

I hope this is easy to follow and it actually works for you. 🙂

like image 51
Zamorite Avatar answered Sep 17 '22 16:09

Zamorite