Flutter auth firebase getx setstate() called after dispose

8 浏览
0 Comments

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 _firebaseUser;

late Rx _googleSignInAccount;

//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(_auth.currentUser);

_googleSignInAccount = Rx(googleSignIn.currentUser);

// 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 signupGoogle() async {

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 logoutGoogle() async {

print("Sign out!");

await googleSignIn.signOut();

await _auth.signOut();

print(googleSignIn.currentUser?.email);

print("#################################");

print(_firebaseUser.value?.uid);

print("#################################");

//Get.offAllNamed("/LogIn");

}

signIn() {}

}

0
0 Comments

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/…

0
0 Comments

问题的出现原因是在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的错误。

0