You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过方法更新Riverpod FutureProvider的状态?

问题描述

我有一个监听AuthStateChanges流的FutureProvider,它会根据流的内容调整自身状态,但我还希望能手动控制该状态。尝试用方法设置时,系统提示类型不匹配(state是Future类型),试过异步Future方法也没用,请问怎么通过方法控制FutureProvider的状态?

现有代码

enum LoginTypes {
  NotSignedIn,
  Anonymous,
  AppleNoEmail,
  LoggedInEmail,
}

@riverpod
class LoginType extends _$LoginType {
  @override
  Future<LoginTypes> build() async {
    final userAuthState = ref.watch(userAuthProvider);
    print('Stream being called from loginType');

    return userAuthState.when(
      data: (user) async {
        if (user == null) {
          return LoginTypes.NotSignedIn;
        } else {
          try {
            // Access the Firestore collection for users
            CollectionReference userCollection =
                FirebaseFirestore.instance.collection('users');

            // Retrieve the document with the given UID
            DocumentSnapshot userDocument =
                await userCollection.doc(user.uid).get();

            // Check if the document exists
            if (userDocument.exists) {
              // Retrieve and return the user's email
              String? userEmail = userDocument.get('email') as String?;
              print(userEmail);

              if (userEmail == 'anom@gmail.com') {
                return LoginTypes.Anonymous;
              } else if (userEmail == 'apple@gmail.com') {
                return LoginTypes.AppleNoEmail;
              } else {
                return LoginTypes.LoggedInEmail;
              }
            }

            return LoginTypes.NotSignedIn;
          } catch (e) {
            print('Error checking user type: $e');
            return LoginTypes.NotSignedIn;
          }
        }
      },
      loading: () => LoginTypes.NotSignedIn,
      error: (_, __) => LoginTypes.NotSignedIn,
    );
  }

  void setToEmail() {
    state = LoginTypes.LoggedInEmail;
  }

}
解决方案

你的问题核心在于:LoginType是AsyncNotifier(对应FutureProvider),它的state类型是AsyncValue<LoginTypes>,而非直接的LoginTypes枚举值。直接赋值枚举值会导致类型不匹配错误。

要手动控制状态,需要用AsyncValue的静态方法来包装枚举值:

  • 设置成功状态用AsyncData()
  • 设置加载状态用AsyncLoading()
  • 设置错误状态用AsyncError()

修改你的setToEmail方法即可:

void setToEmail() {
  // 用AsyncData包裹枚举值,匹配state的AsyncValue类型
  state = const AsyncData(LoginTypes.LoggedInEmail);
}

额外说明

  1. 如果需要手动触发build方法重新执行(比如刷新自动监听的逻辑),可以在方法里调用:
void refreshLoginType() {
  ref.invalidateSelf();
}
  1. 注意:当userAuthProvider的状态变化时,build方法会重新执行,覆盖你手动设置的状态。如果要避免这种情况,需要在build方法里添加逻辑判断,或者改用StateProvider结合手动更新和流监听的组合方式。

内容的提问来源于stack exchange,提问作者Milan Labus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:20:22