Flutter auth firebase getx setstate() called after dispose
Flutter auth firebase getx setstate() called after dispose
我正在尝试使用getx创建一个flutter应用程序。特别是在认证部分,我遇到了以下错误:
E/flutter ( 8992): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: 在dispose()之后调用了setState():_LogButtonState#3e8d6(生命周期状态:defunct, 未挂载)
E/flutter ( 8992): 如果在不再出现在小部件树中(例如,其父小部件不再在其构建中包含该小部件)的小部件的State对象上调用setState(),则会发生此错误。当代码从计时器或动画回调中调用setState()时,可能会发生此错误。
E/flutter ( 8992): 首选解决方案是在dispose()回调中取消计时器或停止监听动画。另一种解决方案是在调用setState()之前检查此对象的"mounted"属性,以确保该对象仍在树中。
E/flutter ( 8992): 如果在将State对象从树中删除后仍然调用setState(),则此错误可能指示存在内存泄漏。为避免内存泄漏,请在dispose()期间断开对此对象的引用。
E/flutter ( 8992): #0 State.setState. (package:flutter/src/widgets/framework.dart:1085:9)
E/flutter ( 8992): #1 State.setState (package:flutter/src/widgets/framework.dart:1120:6)
E/flutter ( 8992): #2 _LogButtonState.build. (package:sneakychat/Screens/Authentication/login.dart:231:9)
E/flutter ( 8992):
E/flutter ( 8992):
认证控制器的代码如下:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
import '../Globals/globals.dart';
class AuthController extends GetxController {
final FirebaseAuth _auth = firebaseAuth;
late Rx
late Rx
//UserModel get user => _firebaseUser.value;
late GoogleSignIn googleSignIn = GoogleSignIn();
//var a = googleSignIn.currentUser;
@override
onReady() {
super.onReady();
print("##########Im Reasdy###########");
googleSignIn = GoogleSignIn();
// Load current user
_firebaseUser = Rx
_googleSignInAccount = Rx
// Bind Streams for listeners
_firebaseUser.bindStream(_auth.userChanges());
_googleSignInAccount.bindStream(googleSignIn.onCurrentUserChanged);
// Call workers to update auth state
ever(_firebaseUser, _manageAuthState);
ever(_googleSignInAccount, _manageAuthStateGoogle);
}
// Manage the auth state
_manageAuthState(User? user) {
print("Firebase auth state active :D");
if (user == null) {
Get.offAllNamed("/LogIn");
} else {
Get.offAllNamed("/Home");
}
}
// Manage the auth state regarding google's user state
_manageAuthStateGoogle(GoogleSignInAccount? googleSignInAccount) {
print("Google auth state active");
if (googleSignInAccount == null) {
Get.offAllNamed("/LogIn");
} else {
Get.offAllNamed("/Home");
}
}
// Sign with google account
Future
final GoogleSignIn googleSignIn = GoogleSignIn();
try {
final GoogleSignInAccount? googleSignInAccount =
await googleSignIn.signIn();
_googleSignInAccount.value = googleSignInAccount;
if (googleSignInAccount != null) {
final GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount.authentication;
final AuthCredential authCredential = GoogleAuthProvider.credential(
idToken: googleSignInAuthentication.idToken,
accessToken: googleSignInAuthentication.accessToken);
// Bind Google account with Firebase account
UserCredential resultUser = await _auth.signInWithCredential(
authCredential);
print(resultUser.credential);
// Set a listener for the user
_firebaseUser.value = resultUser.user;
print(resultUser.user);
// Store user data if its new
/*User user = User(
name: username,
email: email,
uid: cred.user!.uid,
profilePhoto: downloadUrl,
);
await firestore
.collection('users')
.doc(cred.user!.uid)
.set(user.toJson());*/
Get.offAllNamed("/Home");
}
} catch (exc) {
print(exc);
Get.snackbar(
'Something went wrong',
"We couldn't connect with google's server",
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.amber,
colorText: Colors.white
);
}
}
Future
print("Sign out!");
await googleSignIn.signOut();
await _auth.signOut();
print(googleSignIn.currentUser?.email);
print("#################################");
print(_firebaseUser.value?.uid);
print("#################################");
//Get.offAllNamed("/LogIn");
}
signIn() {}
}
Flutter auth firebase getx setstate() called after dispose这个问题的出现原因是在组件的dispose()方法中调用了setState(),而dispose()方法是在组件销毁后调用的,所以会抛出异常。
解决方法有两种:
1. 在dispose()方法中停止对动画的监听或取消定时器。
2. 在调用setState()之前,先检查state类的mounted属性是否为true。
以下是第二种解决方法的示例代码:
if (mounted) {
setState(() {
// 在这里写你的代码
});
}
如果不清楚在说什么定时器,可以参考以下回答:stackoverflow.com/questions/49340116/…
问题的出现原因是在Flutter中使用Firebase进行身份验证时,使用了GetX状态管理库的SetState()方法,但该方法在对象销毁后被调用,导致出现Flutter auth firebase getx setstate() called after dispose的错误。
解决方法是在onClose()方法中将相关的worker对象进行销毁。具体来说,需要判断应该销毁哪个worker对象,是_ firebaseUser 和_ manageAuthState 还是_ googleSignInAccount 和_ manageAuthStateGoogle。
下面是解决方法的代码示例:
onClose() {
if (_firebaseUser != null && _manageAuthState != null) {
_firebaseUser.close();
_manageAuthState.close();
}
if (_googleSignInAccount != null && _manageAuthStateGoogle != null) {
_googleSignInAccount.close();
_manageAuthStateGoogle.close();
}
}
以上代码中,通过判断对象是否为空来确定要销毁的worker对象,并调用close()方法进行销毁。
通过以上解决方法,可以避免在使用GetX状态管理库时出现Flutter auth firebase getx setstate() called after dispose的错误。