颤动相当于Swift的NotificationCenter?

时间:2018-06-16 00:24:21

标签: dart flutter

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

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

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

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

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

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

1 个答案:

答案 0 :(得分: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'];

    }
}

dispose方法非常重要,否则侦听器将继续侦听并引起问题。

如果需要验证订户是否正在监听,请修改调用和监听方法:

// 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中删除导入的main.dart。