I'm trying to work with Riverpod, specifically with riverpod_generator and since there is not a lot of documentation surrounding this, I'm having trouble setting up a project to make use of all of this. I want to create a provider with the shared_preferences package so I can access this provider globally. It's seems by using this generator you can avoid to know which provider you need (state, future, etc.) which is neat thing I must say but I'm not quite sure I understand the whole scope yet.
First the class that will be the global shared pref provider (although this is not set up correctly, hence the ask for help)
@riverpod // annotation for the riverpod_generator
class SharePrefNotifier extends _$SharePrefNotifier{
@override
SharedPreferences build() {
return _sharedPreferences;
}
// Obtain shared preferences but this is not correct although the compiler asks to be late
late SharedPreferences _sharedPreferences;
int? get getPin =>
_sharedPreferences.getInt(_pinKey);
Future<void> setPin(int? pinNumber) async => await _sharedPreferences.setInt(_pinKey, pinNumber);
Future<void> removePin() async => await _sharedPreferences.remove(_pinKey);
Future<void> deleteAll() async => await _sharedPreferences.clear();
}
When I fix the setup for shared pref provider, I want to access it in another provider:
@riverpod
class SettiingPinNotifier extends _$SettiingPinNotifier {
// referencing the shared_pred notifier on the top of the scope if possible so I can reference it anywhere in this provider if I have multiple methods
final sharedPrefProvider = ref.read(sharedPrefProvider.notifer);
@override
SomeDataState build() {
return const SomeDataState();
}
void setUpAPin(int? number) {
sharedPrefProvider.setPin(number); // referencing the shared pref provider and setup a pin number
state = state.copyWith(pin: number); // adding it to the state so I can change the UI accordingly
}
}
What is the best approach here BUT using the said riverpod_generator/riverpod_annotation? Thanks in advance for your help.
We don't have an actual instance of SharedPreferences, and we can't get one except asynchronously, thus creating the following dummy provider.
@riverpod
SharedPreferences sharedPreferences(ref) {
throw UnimplementedError();
}
After that in the main.dart
final prefs = await SharedPreferences.getInstance();
return runApp(
ProviderScope(
overrides: [
// Override the unimplemented provider with the value gotten from the plugin
sharedPreferencesProvider.overrideWithValue(prefs),
],
child: const MyApp(),
),
);
And finally create a service that deals with the SharedPreferences
instance, and a provider for it.
@riverpod
SharedPreferencesService sharedPreferencesService(SharedPreferencesServiceRef ref) {
final sharedPreferences = ref.watch(sharedPreferencesProvider);
return SharedPreferencesService(sharedPreferences);
}
class SharedPreferencesService {
SharedPreferencesService(this.sharedPreferences);
final SharedPreferences sharedPreferences;
Future<void> setPin(int? pinNumber) async => await sharedPreferences.setInt(_pinKey, pinNumber);
// add all methods, getters, and etc.
}