Call provider before runApp flutter

77 Views Asked by At

I having setting up local notifications in my flutter app using flutter_local_notifications.

In the example provided on the page the configurations are done before runApp. But I am defining the local notification plugin as riverpod provider to have easier access to the plugin wherever in my code.

It looks as follows:

@riverpod
Future<void> setupFlutterNotifications(SetupFlutterNotificationsRef ref) async {
  final notificationService = ref.watch(notificationServiceProvider);
  await notificationService.setupFlutterNotifications();
}

@riverpod
Future<bool?> requestNotificationPermissions(
  RequestNotificationPermissionsRef ref,
) async {
  final notificationService = ref.watch(notificationServiceProvider);
  return notificationService.requestPermissions();
}

@Riverpod(keepAlive: true)
NotificationService notificationService(NotificationServiceRef ref) {
  return NotificationService(
      ref, FlutterLocalNotificationsPlugin(), FirebaseMessaging.instance);
}

class NotificationService {
  NotificationService(this.ref, this._flutterLocalNotifications, this._fcm);...

  Future<void> showLocalNotification({
    required String title,
    required String body,
 }) async {
   return _flutterLocalNotifications.show(
     0,
     title,
     body,
     _notificationDetails,
     payload: 'No payload yet!',
 );

}

Now, how do I manage to call the provider before runApp? I want to do something like:

await ref.watch(setupFlutterNotificationsProvider.future);
await ref.watch(requestNotificationPermissionsProvider.future);
1

There are 1 best solutions below

2
Ruble On BEST ANSWER

You can do asynchronous loading in main:

Future<void> main() async {
  
  final container = ProviderContainer();
  await container.read(setupFlutterNotificationsProvider.future);
  await container.read(requestNotificationPermissionsProvider.future);
  
  return runApp(
    UncontrolledProviderScope(
      container: container,
      child: const MyApp(),
    ),
  );
}

And then use requireValue in widgets:

@override
Widget build(BuildContext context, WidgetRef ref) {
  final notificationPermissions = ref.watch(requestNotificationPermissionsProvider).requireValue;

  return ...;
}

But I would recommend rethinking your architecture:

  • setupFlutterNotifications should not be a provider
  • notificationServiceProvider - it is better to use NotifierProvider based on a class for this purpose.