Flutter Riverpod: обновление страницы за кадром с помощью уведомителя состояния

#flutter #refresh #riverpod

#flutter #обновить #riverpod

Вопрос:

Я использую StateNotifier и Riverpod. У меня есть страница уведомлений, которая содержит список уведомлений. Когда приходит уведомление, я запускаю обновление для уведомления. Однако, когда я перехожу на страницу уведомлений, она по-прежнему использует старую (кэшированную?) Список.

Как обновить страницу за кадром?

Сообщение переднего плана

 FirebaseMessaging.onMessage.listen((RemoteMessage message) {
  _localNotification.showLocalNotification(message);
  ProviderContainer().read(notificationProvider).getNotification();
});
 

Фоновое сообщение

 Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();

  final LocalNotification localNotification = LocalNotification();
  await localNotification.init();
  localNotification.showLocalNotification(message);
  ProviderContainer().read(notificationProvider).getNotification();
}
 

NotificationProvider

 Future<void> getNotification() async {
  try {
    state = const NotificationLoadingState();
    _notificationList = await _notificationRepository.getNotification();
    state = NotificationLoadedState(_notificationList); // ==> I get a new list here
  } catch (e, s) {
    state = const NotificationErrorState('error fetching notification');
  }
}
 

Пользовательский интерфейс

 final state = watch(notificationProvider.state);
if (state is NotificationLoadingState) {
  return _buildLoading();
} else if (state is NotificationLoadedState) {
  return _buildLoaded(state.notificationList); // ==> I still get the old list here
} else if (state is NotificationErrorState) {
  return _buildError(state.message);
}
 

Редактировать:

Мне удалось решить обработчик сообщений переднего плана с помощью navigatorKey.currentContext .

Тем не менее, я до сих пор не решил обработчик фоновых сообщений. Я попытался изменить свой main.dart для использования UncontrolledProviderScope с глобальным ProviderContainer , который затем был вызван из обработчика фоновых сообщений. Это все еще не обновляется.

Ответ №1:

С помощью этой строки вы создаете новый экземпляр для своих поставщиков :

  ProviderContainer().read(notificationProvider).getNotification();
 

для получения существующего экземпляра ProviderContainer необходимо использовать контекст:

 context.read(notificationProvider).getNotification();
 

или, если вы не находитесь внутри пользовательского интерфейса, создайте зависимости между вашими поставщиками

Комментарии:

1. Вы правы. Мне удалось обновить его с помощью navigatorKey.currentContext . Есть ли у вас какой-либо пример того, как добавлять зависимости между поставщиками? Используете ли вы ProviderReference ? Поскольку я все еще немного теряюсь при вызове его из-за пределов пользовательского интерфейса. Я не использую ProviderContainer then?

2. Я попытался изменить свой main.dart для использования UncontrolledProviderScope с глобальным ProviderContainer , который сказал, что контейнер — это тот, который я вызвал из обработчика фоновых сообщений. Тем не менее, это все равно не освежает.

3. Используйте ProviderReference для добавления зависимостей между поставщиками. Больше ничем не могу вам помочь, так как я не знаком с firebase и streams. Но вы должны создать поставщика для вашего экземпляра Firebase, StreamProvider для вашего потока сообщений on и сделать ваш notificationProvider зависимым от него, вызвав ref.watch (StreamProvider). Таким образом, каждый раз, когда ваш поток выдает значение, ваш поставщик уведомлений будет повторно создан с новым значением