简体   繁体   English

使用 Flutter 登录 Google:错误代码 -4

[英]Google Sign-In With Flutter: Error Code -4

I currently try to implement google_sign_in package in Flutter ( https://pub.dartlang.org/packages/google_sign_in ).我目前尝试在 Flutter ( https://pub.dartlang.org/packages/google_sign_in ) 中实现 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 ).为此,我遵循了他们存储库的示例( 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 .在“initState”中的那个例子中是一个调用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.我在 iOS 中尝试了这段代码。 On my first App Start, it worked well.在我的第一个 App Start 中,它运行良好。 But since I logged out I get an error here all the time I restart my app.It is the following PlatformException:但是自从我注销后,我每次重新启动我的应用程序时都会收到一个错误。它是以下 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.我在问题Google Sign-In Error -4 中发现错误代码是因为钥匙串中缺少身份验证。

The solution while swift programming is to call the method * hasAuthInKeychain* before the try to signInSilently.快速编程时的解决方案是在尝试 signInSilently 之前调用方法 * hasAuthInKeychain*。 My problem is that the GoogleSignIn class in the flutter package has no function named like this.我的问题是flutter包中的GoogleSignIn类没有这样命名的函数。

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.不知何故,它没有捕获 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):我不知道这是否会有所帮助:signInSilently() 正在调用一个方法,其中有以下调用(google_sign_in.dart,第 217 行):

await channel.invokeMethod(method)

In platform_channel.dart there is a call在 platform_channel.dart 中有一个调用

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编辑 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.我再次重新启动了 android studio 并在没有调试模式的情况下运行了一次应用程序。

You could just check if the sign in failed by handling the PlatformException like this:您可以通过像这样处理PlatformException检查登录是否失败:

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();这是捕获错误并运行 _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 .在这种情况下,我从改变signInsignOut 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;
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM