首页 文章

颤动相当于Swift的NotificationCenter?

提问于
浏览
0

我正在使用FirebaseMessaging向我的Flutter应用发送推送通知 . 这些通知包含聊天详细信息

如果应用程序当前处于活动状态且用户位于聊天页面,则应更新页面以显示新消息(我可以处理) .

如果应用程序位于任何其他页面上,则应显示本地通知/吐司 .

我的问题是,如何将通知转发到聊天页面?

我在根页面上监听FirebaseMessaging . 我可以使用 ModalRoute.of(context).isCurrent 来确定通知进入时根页是否是当前页面 . 当活动页面是活动页面时,如何将通知广播到聊天页面?

在Swift中,我使用NotificationCenter从应用代表发送数据,聊天页面会监听它 . 我希望Flutter能有类似的东西 .

1 回答

  • 0

    我找到了一个解决方案,我希望它可以帮助处于类似情况的其他人 .

    我找到了包Dart Message Bus

    它可以完成我需要的一切,并且可以更轻松地处理Streams . 我确实需要添加一个额外的方法(参见结尾) .

    由于说明有点神秘,这就是我如何使它工作 .

    //main.dart
    
    import 'package:dart_message_bus/dart_message_bus.dart';
    
    
    //global variable
    final globalBus = new MessageBus();
    
    class _MyHomePageState extends State<MyHomePage> {
    
       // set up firebase messaging here
    
       @override
       void initState() {
           super.initState();
           _setupPushNotifs;
       }
    
       _setupPushNotifs() {
            _firebaseMessaging.configure(
                onMessage: (Map<String, dynamic> message) {
                    _processChatPush(message);
                },
            );
       }
    
       _processChatPush(Map<String, dynamic> message) async {
          String messageID = message['messageID'];
          globalBus.publish(new Message('newChat', data: "$messageID"));
      }
    }
    
    //chat.dart
    import 'package:dart_message_bus/dart_message_bus.dart';
    
    import 'main.dart';
    
    class _ChatPageState extends State<ChatPage> {
        StreamSubscription streamListener;    
    
        @override
        void initState() {
            super.initState();
            _listen();
        }
    
        @override
        void dispose() {
            streamListener.cancel();
            streamListener = null;
        }
    
        _listen() async {
        streamListener = globals.globalBus.subscribe('newChat', (Message m) async {
            Map<String, dynamic> message = m.data;
            String messageID = message['messedID'];
    
        }
    }
    

    处置方法非常重要,否则听众会继续倾听并引发问题 .

    如果您需要验证订阅者实际正在侦听,请修改调用和侦听方法:

    // main.dart
    _processChatPush(Map<String, dynamic> message) async {
        String messageID = message['messageID'];
    
        var callbackMessage = await globalBus.publish(
            new Message('newChat', data: "$messageID"),
            waitForKey: 'ackChat',
            timeout: const Duration(seconds: 2)
        );
        if(callbackMessage.isEmpty) {
            // means the another service's message was not received
            // and timeout occured.
            // process the push notification here
        } else {
            // the callback from another service received
            // and callbackMessage.data contains callback-data.
            // the push notification has been handled by chat.dart
        }
    }
    
    
    // chat.dart
    _listen() async {
        streamListener = globals.globalBus.subscribe('newChat', (Message m) async {
            Map<String, dynamic> message = m.data;
            String messageID = message['messageID'];
    
            var data = "ack";
            var ack = new Message('ackChat', data: data);
            globalBus.publish(ack);
        }
    }
    

    我不得不添加一个额外的方法,以便在不再需要时关闭发布流 .

    添加到包源中的message_bus.dart中的类MessageBus的末尾:

    close() {
        _streamController.close();
        _streamController = null;
    }
    

    然后你可以处理流:

    void dispose() {
         globalBus.close(); 
         super.dispose();
     }
    

    我最终将globalBus变量放在库文件中 . 然后在main.dart和chat.dart中导入该库,并从chat.dart中删除import main.dart .

相关问题