[英]Flutter: Platform Exception upon cancelling Google Sign In flow
这是我的 pubspec.yaml。 我正在使用 Flutter:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
http: ^0.11.3
#Google Sign In
google_sign_in: 3.0.3
firebase_auth: ^0.5.18
flutter_svg: ^0.5.0
我可以很好地进行身份验证,登录结构可以正常工作,但是如果我在 Google 登录并且我通过点击物理设备(S7 Edge)上的后退按钮取消了 Google 的身份验证流程,应用程序将锁定并返回:
Exception has occurred.
PlatformException(sign_in_failed, Status{statusCode=ERROR, resolution=null}, null)
这是情况的日志。 在我看来,它好像默默地失败了:
I/InputMethodManager(13050): startInputInner - mService.startInputOrWindowGainedFocus
D/ViewRootImpl@3c3c6cd[SignInHubActivity](13050): MSG_WINDOW_FOCUS_CHANGED 0
D/ViewRootImpl@3c3c6cd[SignInHubActivity](13050): MSG_WINDOW_FOCUS_CHANGED 1
V/InputMethodManager(13050): Starting input: tba=android.view.inputmethod.EditorInfo@4d4a683 nm : com.xYNP82hMsgxfvzA.pqfrontend ic=null
I/InputMethodManager(13050): startInputInner - mService.startInputOrWindowGainedFocus
D/ViewRootImpl@3c3c6cd[SignInHubActivity](13050): MSG_WINDOW_FOCUS_CHANGED 0
D/ViewRootImpl@a981422[MainActivity](13050): MSG_WINDOW_FOCUS_CHANGED 1
V/InputMethodManager(13050): Starting input: tba=android.view.inputmethod.EditorInfo@5990000 nm : com.xYNP82hMsgxfvzA.pqfrontend ic=null
I/InputMethodManager(13050): startInputInner - mService.startInputOrWindowGainedFocus
I/FlutterActivityDelegate(13050): onResume setting current activity to this
D/OpenGLRenderer(13050): eglDestroySurface = 0x7cb041df50
D/ViewRootImpl@3c3c6cd[SignInHubActivity](13050): Relayout returned: old=[0,0][1440,2560] new=[0,0][1440,2560] result=0x5 surface={valid=false 0} changed=true
D/ViewRootImpl@3c3c6cd[SignInHubActivity](13050): dispatchDetachedFromWindow
D/InputEventReceiver(13050): channel 'a2e7010 com.xYNP82hMsgxfvzA.pqfrontend/com.google.android.gms.auth.api.signin.internal.SignInHubActivity (client)' ~ Disposing input event receiver.
D/InputEventReceiver(13050): channel 'a2e7010 com.xYNP82hMsgxfvzA.pqfrontend/com.google.android.gms.auth.api.signin.internal.SignInHubActivity (client)' ~NativeInputEventReceiver.
网上没找到解决办法,谁能帮帮我?
更新:我刚刚在日志中收到异常通知:
E/flutter (13050): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter (13050): PlatformException(sign_in_failed, Status{statusCode=ERROR, resolution=null}, null)
E/flutter (13050): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:547:7)
E/flutter (13050): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:279:18)
E/flutter (13050): <asynchronous suspension>
E/flutter (13050): #2 GoogleSignIn._callMethod (package:google_sign_in/google_sign_in.dart:183:58)
E/flutter (13050): <asynchronous suspension>
E/flutter (13050): #3 GoogleSignIn._addMethodCall (package:google_sign_in/google_sign_in.dart:222:20)
E/flutter (13050): #4 GoogleSignIn.signIn (package:google_sign_in/google_sign_in.dart:293:48)
E/flutter (13050): #5 handleSignIn (file:///C:/Users/dark_/picquest-dev/pq_frontend/lib/src/services/auth.dart:9:62)
E/flutter (13050): <asynchronous suspension>
E/flutter (13050): #6 main (file:///C:/Users/dark_/picquest-dev/pq_frontend/lib/main.dart:18:10)
E/flutter (13050): <asynchronous suspension>
E/flutter (13050): #7 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:279:19)
E/flutter (13050): #8 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:165:12)
它指向我写的身份验证服务:这是:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'dart:async';
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _auth = FirebaseAuth.instance;
Future<FirebaseUser> handleSignIn() async {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final FirebaseUser user = await _auth.signInWithGoogle(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
print("signed in " + user.displayName);
return user;
}
Future<Null> handleSignOut() async {
await _auth.signOut();
await _googleSignIn.signOut();
}
这就是所谓的:
void main() {
//Default unauthenticated home page
try {
auth.handleSignIn();
} catch(e) {
print(e);
}
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown
]);
runApp(new MaterialApp(
title: 'Test',
home: _defaultHome,
theme: new ThemeData(
primaryColor: Colors.white
),
routes: <String, WidgetBuilder> {
'/onboarding/basic-info': (BuildContext context) => new UserOnBoarding_BasicInfo_Page(),
//'/onboarding/interests': (BuildContext context) => new UserOnBoarding_Interests_Page(),
'/avatar-repository': (BuildContext context) => new AvatarRepositoryPage(),
'/login': (BuildContext context) => new LoginPage(),
'/app/settings': (BuildContext context) => new AppSettingsPage()
},
)
);
}
您可以使用catchError
捕获错误,如下所示:
Future<FirebaseUser> handleSignIn() async {
final GoogleSignInAccount googleUser =
await _googleSignIn.signIn().catchError((onError) {
print("Error $onError");
});
if (googleUser != null) {
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final FirebaseUser user = await _auth
.signInWithGoogle(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
)
.catchError((onError) {
print("error $onError");
});
if (user != null) {
print("signed in " + user.displayName);
return user;
}
}
return null;
}
根据google_sign_in.dart
signIn()
函数的评论,请求取消应该返回null
而不是抛出PlatformException
:
/// Returned Future resolves to an instance of [GoogleSignInAccount] for a /// successful sign in or `null` in case sign in process was aborted.
我在此处的 Flutter 存储库中针对此错误提出了问题
现在,您必须坚持手动捕获错误
正如@monojmnj 所说,在发布模式下不会发生此错误,我认为这是 IDE 导致的错误,因为当您在终端中运行您的应用程序时,不会导致任何异常。
我可以确认这个问题截至今天仍然存在(但仅在调试模式下) ,并且当在发布模式下取消登录时,应用程序不会崩溃/冻结并继续运行,所以我觉得这主要是抛出的 ide异常和 dart 无法捕获它。所以直到它得到修复,所以一个简单的解决方法是使用应用程序的发布版本。
注意:确保对应用程序进行签名并在 firebase 控制台中输入哈希值,否则 google 登录将无法在发布模式下工作
我最近也遇到了这个错误,我发现.catchError()
回调没有在调试模式下被调用(当你在 VSCode 中点击Run->Start Debugging
按钮时)。
但是,当您输入 flutter run -d 时, .catchError()
方法会被回调,因为它不在调试模式下。
要获得首选模拟器的代码,请在终端中粘贴以下代码行:
instruments -s devices
如果这不起作用,您也可以尝试粘贴以下内容:
xcrun simctl list
.catchError()
方法将像以前一样被调用,并且其中的代码将按预期执行!
此外,应用程序不会再因PlatformException()
而崩溃,而是您将获得如下日志:
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The getter 'uid' was called on null.
Receiver: null
我在 Google Sign In 中也.catchError()
过这个问题,其中.catchError()
没有被调用!
总之,如果您在处理 Firebase 身份验证中的错误时遇到一些错误,您应该首先尝试首先通过终端运行。 谢谢,我希望这会有所帮助!
系统映像需要“ google playstore服务 ”
例如:Google Play Intel x86 Atom System Image(系统映像; android28; google_apis_playstore ; x86)
在使用Google登录之前,请确保您的系统映像具有“ google paly service ”。 通过AVD管理员检查。 如果您的模拟器的系统映像包含“ google paly service ”,您将在模拟器名称旁边看到“ google paly ”图标。
我在此处找到的中断 Google 登录流程的一种解决方法是执行以下操作:
找到包: package:flutter/src/services/platform_channel.dart
并更改:
final Map<dynamic, dynamic> result = await invokeMethod<Map<dynamic, dynamic>>(method, arguments);
return result?.cast<K, V>();
到:
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
}
}
截至今天,我的发布版本遇到了这个问题。 在调试模式下取消 Google 登录工作正常。 在进行发布构建并上传到 TestFlight 后,当我尝试此功能时,该应用程序会崩溃。 甚至我的应用也因此被 App Store 拒绝。 Android build thou 我没有遇到这个问题。 修复此错误的唯一方法是添加 null 检查。 即使用 try 也能捕捉到 IoS App 曾经崩溃过。 希望这对与我在同一条船上的人有所帮助,因为我花了 3 天时间才弄清楚并解决了它
try {
// Trigger the authentication flow
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
if(googleUser == null){
return LoginUserData(functionRespData: FunctionRespData( error: "login-error"));
}
// Obtain the auth details from the request
final GoogleSignInAuthentication? googleAuth =
await googleUser?.authentication;
// Create a new credential
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
// UserCredential? userCredential = await FirebaseAuth.instance.currentUser
// ?.linkWithCredential(credential);
// Once signed in, return the UserCredential
UserCredential userCredential =
await FirebaseAuth.instance.signInWithCredential(credential);
return LoginUserData(userData:_userFromFirebase(userCredential.user));
} on FirebaseAuthException catch (e) {
return LoginUserData(functionRespData: FunctionRespData(error: e.message));
} catch(e){
return LoginUserData(functionRespData: FunctionRespData( error: "login-error"));
}
如果您取消流程,对final GoogleSignInAccount googleUser = await _googleSignIn.signIn()
的调用将返回 null 值。 流的 rest 取决于不是 null 的值,所以如果是这种情况,请尽早返回。
final GoogleSignInAccount googleUser = await _googleSignIn.signIn()
if (googleUser == null) {
return; // or throw an error
}
在我的项目案例中
只需通过终端运行它,当您使用 vscode (f5) 运行时会发生这种情况,但是当您在终端上使用flutter run
时,不会发生异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.