Функция Firebase OnMessage обновляет виджет - PullRequest
1 голос
/ 02 октября 2019

Я использую облачные сообщения Firebase для отправки уведомлений в мое приложение, содержащее страницу чата.

Я определил функции push-уведомлений Firebase на main.dart, как показано ниже:

_firebaseMessaging.configure(
   onMessage: (Map<String, dynamic> message) async {
     print("onMessage: $message");
     //_showItemDialog(message);
   },
   onBackgroundMessage: myBackgroundMessageHandler,
   onLaunch: (Map<String, dynamic> message) async {
     print("onLaunch: $message");
     //_navigateToItemDetail(message);
   },
   onResume: (Map<String, dynamic> message) async {
     print("onResume: $message");
     //_navigateToItemDetail(message);
   },
 );

Когда открывается виджет чата, и я получаю push-уведомление, мой метод OnMessage достигается нормально.

Вопрос в том, каков наилучший способ обновить страницу чата, учитывая, что открытая страница отличается от той, гдедостигнуто OnMessage функция объявлена?

1 Ответ

3 голосов
/ 02 октября 2019

Я использовал следующий фрагмент кода для другого вопроса в StackOverflow. Но проблема в этом полностью отличается от вашей, поэтому вставьте соответствующий код.

Вы можете использовать BLOC здесь. FCM / NotificationService будет отправлять уведомления на BLOC / NotificationsBloc, и все виджеты, которым нужны уведомления, могут подписаться на уведомления. Пример реализации

BLOC

import 'package:rxdart/rxdart.dart';

class LocalNotification {
  final String type;
  final Map data;

  LocalNotification(this.type, this.data);
}

class NotificationsBloc {
  NotificationsBloc._internal();

  static final NotificationsBloc instance = NotificationsBloc._internal();

  final BehaviorSubject<LocalNotification> _notificationsStreamController = BehaviorSubject<LocalNotification>();

  Stream<LocalNotification> get notificationsStream {
    return _notificationsStreamController;
  }

  void newNotification(LocalNotification notification) {
    _notificationsStreamController.sink.add(notification);
  }

  void dispose() {
    _notificationsStreamController?.close();
  }
}

Слушатель FCM (NotificationService)

import 'package:firebase_messaging/firebase_messaging.dart';

import 'notifications_bloc.dart';

class LocalNotificationService {
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  bool _started = false;

  LocalNotificationService._internal();

  static final LocalNotificationService instance = LocalNotificationService._internal();

  // ********************************************************* //
  // YOU HAVE TO CALL THIS FROM SOMEWHERE (May be main widget)
  // ********************************************************* //
  void start() {
    if (!_started) {
      _start();
      _started = true;
      _refreshToken();
    }
  }

  void _refreshToken() {
    _firebaseMessaging.getToken().then(_tokenRefresh, onError: _tokenRefreshFailure);
  }

  void _start() {
    _firebaseMessaging.requestNotificationPermissions();
    _firebaseMessaging.onTokenRefresh.listen(_tokenRefresh, onError: _tokenRefreshFailure);
    _firebaseMessaging.configure(
      onMessage: _onMessage,
      onLaunch: _onLaunch,
      onResume: _onResume,
    );
  }

  void _tokenRefresh(String newToken) async {
    print(" New FCM Token $newToken");
  }

  void _tokenRefreshFailure(error) {
    print("FCM token refresh failed with error $error");
  }

  Future<void> _onMessage(Map<String, dynamic> message) async {
    print("onMessage $message");
    if (message['notification'] != null) {
      final notification = LocalNotification("notification", message['notification'] as Map);
      NotificationsBloc.instance.newNotification(notification);
      return null;
    }
    if (message['data'] != null) {
      final notification = LocalNotification("data", message['data'] as Map);
      NotificationsBloc.instance.newNotification(notification);
      return null;
    }
  }

  Future<void> _onLaunch(Map<String, dynamic> message) {
    print("onLaunch $message");
    return null;
  }

  Future<void> _onResume(Map<String, dynamic> message) {
    print("onResume $message");
    return null;
  }
}

Наконец-то в вашем виджете

  Stream<LocalNotification> _notificationsStream;

  @override 
  void initState() {
    super.initState();
    _notificationsStream = NotificationsBloc.instance.notificationsStream;
    _notificationsStream.listen((notification) {
      // TODO: Implement your logic here
      print('Notification: $notification');
    });
  }

  @override
  void dispose() {
    _notificationsStream?.dispose();
  }

Надеюсь, это то, что выищем.

...