Flutter+Firebase 将匿名用户升级到 GoogleSignIn 时出错(给定字符串为空或 null)
Posted
技术标签:
【中文标题】Flutter+Firebase 将匿名用户升级到 GoogleSignIn 时出错(给定字符串为空或 null)【英文标题】:Flutter+Firebase error upgrading anonymous user to GoogleSignIn (Given String is empty or null) 【发布时间】:2019-06-29 23:43:23 【问题描述】:我在 Flutter 中有一个匿名帐户,我正在尝试使用 Google 的 AuthCredential 对其进行升级。我已验证凭据是使用有效的 accessToken 和 idToken 创建的。
所以如果auth.currentUser()
是我的匿名FirebaseUser,则在下面调用linkAccountToGoogle()
会导致错误。
/// Upgrade an anonymous account by linking it to a Google account.
Future<FirebaseUser> linkAccountToGoogle() async
final credential = await _getGoogleAuthCredential();
if (credential != null)
try
return auth.linkWithCredential(credential); // <=== THROWS ERROR
catch (e)
print(e);
return null;
/// Tries to sign-in silently first. May return `null`.
Future<AuthCredential> _getGoogleAuthCredential() async
GoogleSignInAccount account;
try
account = await _googleAuthService.signInSilently() ??
await _googleAuthService.signIn();
catch (e)
print(e);
final googleAuth = await account?.authentication;
if (account == null)
print('Unable to retrieve Google account.');
else if (googleAuth == null)
print('Unable to authenticate to Google account ($account.email).');
else
// print(
// 'accessToken: $googleAuth.accessToken, idToken: $googleAuth.idToken');
return GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken, idToken: googleAuth.idToken);
return null;
堆栈跟踪
I/flutter ( 3038): Credential: Instance of 'AuthCredential'
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): Failed to handle method call
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): java.lang.IllegalArgumentException: Given String is empty or null
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at com.google.android.gms.common.internal.Preconditions.checkNotEmpty(Unknown Source:5)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at com.google.firebase.auth.EmailAuthProvider.getCredential(Unknown Source:2)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at io.flutter.plugins.firebaseauth.FirebaseAuthPlugin.handleLinkWithEmailAndPassword(FirebaseAuthPlugin.java:272)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at io.flutter.plugins.firebaseauth.FirebaseAuthPlugin.onMethodCall(FirebaseAuthPlugin.java:122)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:200)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at io.flutter.view.FlutterNativeView$PlatformMessageHandlerImpl.handlePlatformMessage(FlutterNativeView.java:188)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:202)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at android.os.MessageQueue.next(MessageQueue.java:325)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at android.os.Looper.loop(Looper.java:142)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at android.app.ActivityThread.main(ActivityThread.java:6694)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
E/MethodChannel#plugins.flutter.io/firebase_auth( 3038): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
E/flutter ( 3038): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(error, Given String is empty or null, null)
E/flutter ( 3038): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:564:7)
E/flutter ( 3038): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:302:33)
E/flutter ( 3038): <asynchronous suspension>
E/flutter ( 3038): #2 FirebaseAuth.linkWithCredential (file:///home/jacob/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.8.0+1/lib/src/firebase_auth.dart:371:54)
我的尝试
我尝试链接的 Google 帐户已经是该项目的用户,因此我从 Firebase 控制台中删除了该 Google 用户。然后再次尝试使用flutter clean
flutter run
。
【问题讨论】:
最近的更新似乎有很多错误(可能部分与 AndroidX 升级有关)。我也遇到了其中一些问题,但决定降级。这是一篇谈论更多github.com/flutter/flutter/issues/27156的帖子 @Jacob 您找到解决方案或解决方法了吗?我的项目中也需要这个 实际上没有,还没有。我将google_sign_in
降级为 ^3.0.0 但这不起作用。也许如果我也降级其他 AndroidX 包,我没有花太多时间在它上面。
最近没有更新??
@ShadyBoshra 是的,显然它已在 firebase_auth 0.11.0 中修复
【参考方案1】:
必须先触发 Google 登录流程,然后才能关联要关联的帐户的身份验证凭据。根据给出的错误,Google Sign-in 的 AuthCredential 中的数据很可能丢失了一些东西,这就是它抛出 Given String is empty or null
我已经使用firebase_auth: ^3.3.4
尝试了下面的代码,它在我身上运行良好,没有问题。
// Trigger Google Auth flow.
final GoogleSignInAccount googleUser = await GoogleSignIn().signIn();
// Obtain auth details from the request.
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
// Create a new credential.
final GoogleAuthCredential googleCredential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
// Get current anonymous user.
User anonymousUser = auth.currentUser();
// Link anonymous account with Google account.
await anonymousUser.linkWithCredential(googleCredential);
【讨论】:
以上是关于Flutter+Firebase 将匿名用户升级到 GoogleSignIn 时出错(给定字符串为空或 null)的主要内容,如果未能解决你的问题,请参考以下文章
如何将匿名 Firebase 凭据保存到本地存储以外的其他地方?
升级到 Flutter 2.0 会破坏 Flutter Firebase Web 项目
匿名身份验证用户的这个 Firebase/Firestore 安全规则是不是安全?
使用 SwiftUI、Combine 和 Firebase,我如何在将用户的帐户链接到电子邮件/密码之前验证用户是不是已匿名登录?