【问题标题】:How do i use StateNotifier riverpod to track the changes of enum value我如何使用 StateNotifier Riverpod 来跟踪枚举值的变化
【发布时间】:2021-04-30 12:39:31
【问题描述】:

我正在尝试使用 Riverpod stateNotifier 在用户身份验证期间跟踪枚举的更改以确定要显示的适当屏幕。例如注册、登录、主页或身份验证屏幕,但我在命名构造函数中返回此错误:

超类“StateNotifier”没有零参数构造函数。 尝试在“StateNotifier”中声明一个零参数构造函数,或在“StateNotifier”中显式调用不同的构造函数。 我知道这里有一些我不明白的地方,但我想不通。

这是我的代码:

enum Status {
  unInitialized,
  unauthenticated,
  authenticating,
  authenticated,
  processing
}

class AuthWithEmailPassword extends StateNotifier<Status> {
  AuthWithEmailPassword() : super(Status.authenticated);

  Status _status = Status.authenticated;
  // AuthWithEmailPassword();
  UserServices _userServices = UserServices();

  FirebaseAuth _auth;
  UserModel _userModel;
  User _user;
  Status get status => _status;
  User get user => _user;
  UserModel get userModel => _userModel;

  //Name consturctor of this class
  @override
  AuthWithEmailPassword.initialize()
      : _auth = FirebaseAuth.instance{
    _status = Status.unInitialized;

    _auth.authStateChanges().listen((User value) async {
      _status = Status.unInitialized;

      if (value == null) {
        _status = Status.unauthenticated;

        print('user is signed out');
      } else {
        _userModel = await _userServices.getUserByUid(id: value.uid);
        _status = Status.authenticated;

        _user = value;
        print('user signed in');
      }
    });
  }}

【问题讨论】:

  • 您可以创建一个初始化函数并在您的 StateNotifierProvider 中调用它,而不是使用命名构造函数。如果你愿意,我可以提供一个例子。
  • 是的,请。如果您能提供@Alex Hartford 的示例,我将不胜感激。

标签: flutter dart


【解决方案1】:

您可以创建一个初始化函数并在您的 StateNotifierProvider 中调用它,而不是使用命名构造函数。

例如:

class AuthWithEmailPassword extends StateNotifier<Status> {
  AuthWithEmailPassword() : super(Status.authenticated);

  Status _status = Status.authenticated;
  Status get status => _status;

  final FirebaseAuth _auth = FirebaseAuth.instance;

  User _user;
  User get user => _user;

  UserModel _userModel;
  UserModel get userModel => _userModel;

  bool _init = false;
  late StreamSubscription _sub;

  void initialize() {
    if (_init) return;
    _status = Status.unInitialized;
    _sub = _auth.authStateChanges().listen(_listener);
    _init = true;
  }

  @override
  void dispose() {
    _sub.cancel();
    super.dispose();
  }

  Future<void> _listener(User? value) async {
    _status = Status.unInitialized;

    if (value == null) {
      _status = Status.unauthenticated;

      print('user is signed out');
    } else {
      _userModel = await _userServices.getUserByUid(id: value.uid);
      _status = Status.authenticated;

      _user = value;
      print('user signed in');
    }
  }
}

final authWithEmailPasswordProvider = StateNotifierProvider.autoDispose<AuthWithEmailPassword, Status>((_) {
  return AuthWithEmailPassword()..initialize();
});

【讨论】:

    【解决方案2】:

    感谢 Alex Hartford 在我对这个问题感到绝望时帮助我解决问题。我终于也想出了另一个解决方案,也许有人会喜欢它。

    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:firebase_auth/firebase_auth.dart';
    import 'package:flutter_ecom/controle/userServices.dart';
    import 'package:flutter_ecom/models/userModel.dart';
    import 'package:flutter_riverpod/flutter_riverpod.dart';
    
    enum Status {
      unInitialized,
      unauthenticated,
      authenticating,
      authenticated,
    }
    
    final authStatus = StateNotifierProvider<AuthWithEmailPassword, Status>(
        (ref) => AuthWithEmailPassword.initialize());
    
    class AuthWithEmailPassword extends StateNotifier<Status> {
      FirebaseFirestore firestore = FirebaseFirestore.instance;
      UserServices _userServices = UserServices();
      // Status state = Status.unInitialized;
    
      FirebaseAuth _auth;
      UserModel _userModel;
      User _user;
      // Status get status => _status;
      User get user => _user;
      UserModel get userModel => _userModel;
      String _error;
      String get error => _error;
    
      //Name consturctor of this class
      AuthWithEmailPassword.initialize()
          : _auth = FirebaseAuth.instance,
            super(Status.unInitialized) {
        _auth.authStateChanges().listen((User value) async {
          await Future.delayed(
            const Duration(milliseconds: 4000),
          );
          if (value == null) {
            state = Status.unauthenticated;
            print('user is signed out');
          } else {
            _userModel = await _userServices.getUserByUid(id: value.uid);
            state = Status.authenticated;
            _user = value;
            print('user signed in');
          }
        });
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-02
      • 2021-04-21
      • 2021-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 2010-11-18
      相关资源
      最近更新 更多