I'm stuck with a situation where I am trying to use a RiverPod provider in my Flutter app to represent user preference data. In this case, the user preference data is stored in FireStore.
I'm stuck with understanding how to load provider state from Firestore. Currently, I'm trying to use the "userPreferencesFutureProvider" to load the 'GdUserPreferences" data from a service that calls Firestore, which then pushes the data into "userPreferencesProvider" using the 'overrideWith' method. However, when I access the user preference data via the 'userPreferencesProvider' provider the data loaded from Firestore is not present
final userPreferencesFutureProvider = FutureProvider<bool>( (ref) async {
final p = ref.watch(userPrefsServiceProvider);
GdUserPreferences? aPrefs = await p.load();
if (aPrefs == null) {
aPrefs = GdUserPreferencesUtil.createDefault();
}
userPreferencesProvider.overrideWith((ref) => UserPreferencesNotifier(p,aPrefs!));
return true;
});
final userPreferencesProvider = StateNotifierProvider<UserPreferencesNotifier,GdUserPreferences>((ref) {
return UserPreferencesNotifier(ref.watch(userPrefsServiceProvider),GdUserPreferences());
});
Any suggestions?
Update
Further to the feedback received I have updated my code as shown below, but this still doesn't work...
final userPreferencesFutureProvider = FutureProvider<bool>( (ref) async {
// get service that wraps calls to Firestore
final p = ref.watch(userPrefsServiceProvider);
// load data from Firestore
GdUserPreferences? aPrefs = await p.load();
// if none found then create default values
if (aPrefs == null) {
aPrefs = GdUserPreferencesUtil.createDefault();
}
// push state into a provider that will be used
ref.read(userPreferencesProvider.notifier).update(aPrefs);
// this future returns a boolean as a way of indicating that the data load succeeded.
// elsewhere in the app access to the user preference data is via the userPreferencesProvider
return true;
});
final userPreferencesProvider = StateNotifierProvider<UserPreferencesNotifier,GdUserPreferences>((ref) {
print('default provider');
return UserPreferencesNotifier(ref.watch(userPrefsServiceProvider),GdUserPreferences());
});
class UserPreferencesNotifier extends StateNotifier<GdUserPreferences> {
// service is a wrapper around FireStore collection call
final GdUserPreferencesService service;
UserPreferencesNotifier(this.service, super.state);
void update(GdUserPreferences aNewPrefs) {
print('update state');
state = aNewPrefs;
}
}
The purpose of having a separate FutureProvider and StateNotifierProvider, is that I can insert the FutureProvider when the app first loads. Then when I want to access the user preference data I can use the straight forward StateNotifierProvider, which avoids the complications of having Future Providers all over the app.
Note: using the print methods I can show that the 'update' method is called after the userPreferencesProvider is first created, so I can't understand why the data is not updated correctly