未处理的异常:错误状态:在调用"dispose"后尝试使用StateNotificationer



我正在使用riverpod来管理我的应用程序状态,并与最后一个提供程序作斗争。基本上,我使用的是Firebase身份验证提供程序,并且为每个在auth-uid上匹配的用户都有一个Firestore文档(FirestoreUser(

为了让应用程序正常运行,我需要做以下操作:

  • 当用户通过身份验证时,我需要检索作为流的Firestore文档(FirestoreUser((在auth-uid上匹配的文档(
  • 通过传递将在整个应用程序中使用的uid作为参数,进行api调用(而不是firestore(以检索ProfileUser模型
  • Firestore文档有一个名为sync_required的字段,如果此值设置为true,则调用api并刷新UI,还将sync_required设置为false。这个firestore文档的目的是在应用程序中保持Api数据的同步
  • 如果ProfileUser在应用程序中更新,UI应反映更改,并调用另一个api端点来更新源数据

这是我的供应商。

final firebaseAuthProvider = Provider<FirebaseAuth>((ref) => FirebaseAuth.instance);

final authStateChangeProvider = StreamProvider<User?>((ref) => ref.watch(firebaseAuthProvider).authStateChanges());

final firestoreDatabaseProvider = Provider<FirestoreDatabase?>((ref) {
final auth = ref.watch(authStateChangeProvider);
if (auth.asData?.value?.uid != null) {
return FirestoreDatabase(uid: auth.asData!.value!.uid);
}
return null;
});
final firestoreUserChangeProvider = StreamProvider<FirestoreUser?>((ref) {
return ref.watch(firestoreDatabaseProvider)!.getFirestoreUser();
});
final apiServiceProvider = Provider<ApiService?>((ref) {
final auth = ref.watch(authStateChangeProvider);
if (auth.asData?.value?.uid != null) {
return ApiService(uid: auth.asData!.value!.uid);
}
return null;
});

为了从api中维护ProfileUser的状态,我正在使用StateNotificationer,但它无法正常工作。

我得到的错误是未处理的异常:错误状态:在调用dispose后尝试使用ProfileUserStateNotificationer

class ProfileUserStateNotifier extends StateNotifier<ProfileUser?> {
ApiService? _apiService;
ProfileUserStateNotifier(this._apiService) : super(new ProfileUser()) {
load();
}
void load() async {
var profileUser = await _apiService!.getProfile();
state = profileUser;
}
}
final profileNotifier =
StateNotifierProvider<ProfileUserStateNotifier, ProfileUser?>((ref) {
final firestoreUser = ref.watch(firestoreUserChangeProvider);
final firestoreDb = ref.read(firestoreDatabaseProvider);
firestoreUser.whenData((value) {
if (value!.syncRequired!) {
firestoreDb!.stopSync();
}
});
return ProfileUserStateNotifier(ref.read(apiServiceProvider));
});

firestore_database.dart

Stream<FirestoreUser> getFirestoreUser() {
return ref.doc(uid).snapshots().map((value) => FirestoreUser.fromJson(value.data() as Map<dynamic, dynamic>));
}

api_service.dart

Future<ProfileUser?> getProfile() async {
//call api end point
return profileUser;
}

在执行任何其他操作之前,我如何确保我拥有来自身份验证提供程序、FirestoreUser启动的和ProfileUser对象的uid?

此外,我不确定在主屏幕中是否正确使用了StateNotifer,因为我正在检查null并显示进度指示器。如果api调用返回null,在这种情况下,我的主屏幕将被困在进度指示器中。

@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
body: Consumer(
builder: (context, watch, child) {
var profile = ref.watch(profileNotifier);
if (profile!.username == null) {
return Scaffold(body: Center(child:CircularProgressIndicator()));
} else {
return Scaffold(body: Center(child: Text(profile.username!)));
}

}),
);
}

对不起,我是Flutter和Riverpod的新手,所以如果有任何代码参考或教程链接来解决我的问题,我们将不胜感激。

设法解决了问题,但在更新firestore文档时,api被调用了两次。

final profileAsyncController =
StateNotifierProvider<ProfileAsyncNotifier, AsyncValue<ProfileUser?>>(
(ref) => ProfileAsyncNotifier(ref));
class ProfileAsyncNotifier extends StateNotifier<AsyncValue<ProfileUser?>> {
ProfileAsyncNotifier(this.ref) : super(AsyncLoading()) {
_init();
}
final Ref ref;
void _init() async {
final firestoreUser = ref.watch(firestoreUserChangeProvider);
var profile = await ref.read(apiServiceProvider)!.getProfile();
state = AsyncData(profile);
final firestoreDb = ref.read(firestoreDatabaseProvider);
firestoreUser.whenData((value) {
if (value!.syncRequired!) {
firestoreDb!.stopSync();
}
});
}
}

最新更新