在与提供程序一起使用FirebaseAuth onAuthChange的应用中说明问题

时间:2019-10-03 11:17:26

标签: flutter provider

我正在使用ChangeNotifier进行身份验证  在首页和登录页面之间自动路由的信息。 我可以在代码中的任何地方正确使用它的变量和方法,但是当我使用Provider.of<AuthNotifier>(context).signOut();退出应用程序(通过点击手势识别器)时,它将抛出:

E/flutter (  976): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: A AuthNotifier was used after being disposed.
E/flutter (  976): Once you have called dispose() on an AuthNotifier, it can no longer be used.
E/flutter (  976): #0      ChangeNotifier._debugAssertNotDisposed.<anonymous closure> 
package:flutter/…/foundation/change_notifier.dart:105
E/flutter (  976): #1      ChangeNotifier._debugAssertNotDisposed 
package:flutter/…/foundation/change_notifier.dart:111
E/flutter (  976): #2      ChangeNotifier.notifyListeners 
package:flutter/…/foundation/change_notifier.dart:200
E/flutter (  976): #3      AuthNotifier._onAuthStateChanged 
package:instagram/…/plain_models/auth.dart:142
E/flutter (  976): <asynchronous suspension>
E/flutter (  976): #4      _rootRunUnary  (dart:async/zone.dart:1132:38)
E/flutter (  976): #5      _CustomZone.runUnary  (dart:async/zone.dart:1029:19)
E/flutter (  976): #6      _CustomZone.runUnaryGuarded  (dart:async/zone.dart:931:7)
E/flutter (  976): #7      _BufferingStreamSubscription._sendData  (dart:async/stream_impl.dart:336:11)
E/flutter (  976): #8      _DelayedData.perform  (dart:async/stream_impl.dart:591:14)
E/flutter (  976): #9      _StreamImplEvents.handleNext  (dart:async/stream_impl.dart:707:11)
E/flutter (  976): #10     _PendingEvents.schedule.<anonymous closure>  (dart:async/stream_impl.dart:667:7)
E/flutter (  976): #11     _rootRun  (dart:async/zone.dart:1120:38)
E/flutter (  976): #12     _CustomZone.run  (dart:async/zone.dart:1021:19)
E/flutter (  976): #13     _CustomZone.runGuarded  (dart:async/zone.dart:923:7)
E/flutter (  976): #14     _CustomZone.bindCallbackGuarded.<anonymous closure>  (dart:async/zone.dart:963:23)
E/flutter (  976): #15     _rootRun  (dart:async/zone.dart:1124:13)
E/flutter (  976): #16     _CustomZone.run  (dart:async/zone.dart:1021:19)
E/flutter (  976): #17     _CustomZone.runGuarded  (dart:async/zone.dart:923:7)
E/flutter (  976): #18     _CustomZone.bindCallbackGuarded.<anonymous closure>  (dart:async/zone.dart:963:23)
E/flutter (  976): #19     _microtaskLoop  (dart:async/schedule_microtask.dart:41:21)
E/flutter (  976): #20     _startMicrotaskLoop  (dart:async/schedule_microtask.dart:50:5)

该身份验证退出但不更新状态并引发notifyListeners(); 这是我在提供程序中使用的:

class AuthNotifier with ChangeNotifier {
  FirebaseAuth _auth = FirebaseAuth.instance;
  FirebaseUser _user;
  Status _status = Status.Uninitialized;

  AuthNotifier.instance() : _auth = FirebaseAuth.instance {
    _auth.onAuthStateChanged.listen(_onAuthStateChanged);
  }
  FirebaseAuth get authInfo => _auth;
  Status get status => _status;
  FirebaseUser get user => _user;
  /// <other methods>
  Future signOut() async {
    await _auth.signOut();
    return Future.delayed(Duration.zero);
  }

  Future<void> _onAuthStateChanged(FirebaseUser firebaseUser) async {
    print('[Auth] Noticed Auth Changes: ${firebaseUser.toString()}');
    if (firebaseUser == null) {
      _status = Status.Unauthenticated;
    } else {
      _user = firebaseUser;
      _status = Status.Authenticated;
    }
    print('[Auth] Current Auth Status: ${_status.toString()}');
    notifyListeners();
  }
}

这是我的主要方法:

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(
          builder: (context) => AuthNotifier.instance(),
        ),
      /// <other ChangeNotifierProviders>
      ],
      child: Root(),
    ),
  );
}

这是我使用它在登录名和首页之间自动路由的方式:

class Root extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      onGenerateRoute: generateRoute,
      home: Consumer(
        builder: (context, AuthNotifier userAuth, _) {
          switch (userAuth.status) {
            case Status.Uninitialized:
              // Loading Page
            case Status.Unauthenticated:
            case Status.Authenticating:
              return LoginPage();
            case Status.Authenticated:
              return Home(user: userAuth.user);
          }
        },
      ),
    );
  }
}

我进行了很多搜索,但找不到解决方案。如果可以,我可能会切换到ScopedModel,但是如果我知道如何修复它会更好。

编辑:我已修复它。造成此问题的原因是,登录时我在AuthNotifier上调用了dispose()

0 个答案:

没有答案