Открытие всплывающего окна во флаттере Флаттер при выполнении onBackgroundMessage - PullRequest
1 голос
/ 23 сентября 2019

Я реализовал флаттер onBackgroundMessage, который срабатывает, когда устройство получает сообщение с данными Firebase Cloud Messaging;я должен открыть всплывающее окно, но в этом обработчике событий у меня нет context объекта.Как правильно достичь этого?

Ответы [ 2 ]

1 голос
/ 23 сентября 2019

Если вы хотите отобразить всплывающее окно в приложении, вам не нужно onBackgroundMessage - это только для обработки данных, когда сообщение принимается в фоновом режиме.Нет возможности запустить приложение в момент получения сообщения.

Однако, если пользователь нажмет на уведомление, приложение запустится, и будут вызваны обратные вызовы onResume или onLaunch.

Вы можете уведомить соответствующий экран, чтобы отобразить всплывающее окно, когдаэто происходит.

Вот простая реализация:

В firebase_notification_receiver.dart:

import 'dart:async';
import 'package:firebase_messaging/firebase_messaging.dart';

class NotificationEvent {
  final Map<String, dynamic> content;

  /// whether the notification was delivered while the app was in the foreground
  final bool inApp;

  NotificationEvent({this.content, this.inApp = false});
}

class FirebaseNotificationReceiver extends NotificationReceiver {

  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

  StreamController<NotificationEvent> _controller = StreamController<NotificationEvent>.broadcast();

  StreamSubscription _streamSubscription;

  Function(NotificationEvent) _listener;

  init{

    // add the rest of the code to initialise firebase here

    _firebaseMessaging.configure(

      /// Fires when App was in foreground when receiving the notification
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        _controller.sink.add(NotificationEvent(content: message, inApp: true));
      },

      /// Fires when App was in background when receiving the notification and user has tapped on it
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
        _controller.sink.add(NotificationEvent(content: message));
      }

      /// Fires when App was closed when receiving the notification and user has tapped on it
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
        _controller.sink.add(NotificationEvent(content: message));
      },
    );
    _streamSubscription =
            _controller.stream.listen(_onStreamEvent, onError: (e) {
      print("Notification Stream error $e");
    });
  }

  setListener(Function(NotificationEvent) onData) {
    this._listener = onData;
  }
}

В main.dart:

    // imports go here

    void main(){
       final notificationReceiver = NotificationReceiver.firebase();

      runApp(
        MultiProvider(
          providers: [
            Provider<NotificationReceiver>(
                builder: (_) => notificationReceiver),
            // more providers go here
          ],
          child: App(), // Your custom app class
        ),
      );

    }

В notification_listenable.dart:


import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class NotificationListenable extends StatefulWidget {

  final Widget child;
  final Function(NotificationEvent) onData;

  const NotificationListenable({@required this.child, this.onData});

  @override
  _NotificationListenableState createState() => _NotificationListenableState();
}

class _NotificationListenableState extends State<NotificationListenable> {

  @override
  Widget build(BuildContext context) {
    Provider.of<NotificationReceiver>(context).setListener(widget.onData);
    return widget.child;
  }
}

В my_screen.dart:


/// add your imports here

class MyScreen extends StatefulWidget {

  @override
  HomePageState createState() => HomePageState();
}

class MyScreenState extends State<MyScreen> {

  final _scaffoldKey = GlobalKey<ScaffoldState>();

  void _onNotification(NotificationEvent n) {
    (_scaffoldKey.currentState)?.showSnackBar(
       SnackBar(
         duration: Duration(seconds: 2),
         content: Text("I am a pop up"),
       ),
    ),
 }

 @override
 Widget build(BuildContext context) {

  return NotificationListenable(
    child: YourCustomScreenContent(),
    onData: _onNotification,
  );
}
0 голосов
/ 23 сентября 2019

Я создал класс со статическими методами:

class FirebaseMessagingHandler {
  final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
  final _bloc = AppModule.to.getBloc<FirebaseMessagingHandlerBloc>();

  void setListeners() {
    if (Platform.isIOS) _iOSPermission();

    getToken();

    refreshToken();
  }

  void getToken() {
    firebaseMessaging.getToken().then((token) {
      _bloc.saveToken(token);
      print('DeviceToken = $token');
    });
  }

  void _iOSPermission() {
    firebaseMessaging.configure();
    firebaseMessaging.requestNotificationPermissions(IosNotificationSettings(sound: true, badge: true, alert: true));
    firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
    });
  }

  void refreshToken() {
    firebaseMessaging.onTokenRefresh.listen((token) {
      _bloc.refreshToken(token);
    });
  }

  void showDialog(BuildContext context, Map<String, dynamic> message) {
      // data
  }

  void showErrorDialog(BuildContext context, dynamic error) {
      // data
  }

  void redirectToPage(BuildContext context, Map<String, dynamic> message) {
    // data
  }
}

И на моей домашней странице (страница, которая всегда будет вызываться при открытии моего приложения) я вызываю configure:

class _HomePageState extends State<HomePage> {
  final _fcm = FirebaseMessagingHandler();

  @override
  void initState() {
    super.initState();
    firebaseCloudMessagingListeners();
  }

  void firebaseCloudMessagingListeners() {
    _fcm.firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        try {
          _fcm.showDialog(context, message);
        } catch (e) {
          _fcm.showErrorDialog(context, e);
        }
      },
      onLaunch: (Map<String, dynamic> message) async {
        try {
          _fcm.redirectToPage(context, message);
        } catch (e) {
          _fcm.showErrorDialog(context, e);
        }
      },
      onResume: (Map<String, dynamic> message) async {
        try {
          _fcm.redirectToPage(context, message);
        } catch (e) {
          _fcm.showErrorDialog(context, e);
        }
      },
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...