故障排除Firebase authStateChanges中的“setState()called after dispose()”错误Flutter中的侦听器

9wbgstp7  于 2023-06-07  发布在  Flutter
关注(0)|答案(1)|浏览(191)

我正在使用authStateChanges列表器更改initState()中的signedIn用户帐户变量

@override
  void initState() {
    // Firebase userChange listener
    FirebaseAuth.instance.authStateChanges().listen((User? user) {
      if (user == null) {
        setState(() { // This is line no 43
          signedIn = false;
          userImage =
              "https://XXXX.XXXXXXXX.XXX/News-Manager/v03/static/sample_user.png";
          userName = "Guest";
        });
      } else {
        setState(() {
          signedIn = true;
          userImage = user.photoURL!;
          userName = user.displayName!;
        });
      }
    });

    // Google Sign In listener
    googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount? account) {
        setState(() {
          _currentUser = account;
        });
        if (_currentUser != null) {}
    });

    // Check if user is already signed in
    googleSignIn.signInSilently();

    super.initState();
  }

有时(不总是)我会犯这样的错误:

E/flutter ( 5961): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: setState() called after dispose(): _SettingsState#60dee(lifecycle state: defunct, not mounted)
E/flutter ( 5961): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
E/flutter ( 5961): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
E/flutter ( 5961): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
E/flutter ( 5961): #0      State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1103:9)
E/flutter ( 5961): #1      State.setState (package:flutter/src/widgets/framework.dart:1138:6)
E/flutter ( 5961): #2      _SettingsState.initState.<anonymous closure> (package:kutchsetu/screens/Settings.dart:43:9)

最初我认为这是因为谷歌登录打开了一个弹出窗口的帐户选择。
但这是不是错误的情况下也来登录时没有弹出的帐户选择完成。
其他解决方案建议在调用setState()之前使用if(mounted),但如果listner没有赋值,因为它没有进入if(mounted),它将破坏功能。
有谁知道是什么原因在authChange列表?

qni6mghb

qni6mghb1#

这个问题的发生主要是因为你的状态已经被释放了。我们无法从您的代码中了解小部件树中发生了什么。因此,您的页面随时都有可能被释放,您可以通过使用State类的“mounted”属性来处理此问题。只要小部件不在小部件树中,此属性就为false。所以你可以在每次使用setState时像这样检查:

if(mounted) {
    setState((){});
}

相关问题