在 Flutter Windows 应用中使用 Firebase 云消息传递

Von*_*ian 8 windows desktop dart flutter

我已经检查了 firebase_dart 和 flutterfire 包,但它们都没有提供可供使用的 firebase FirebaseMessaging 类。有什么方法可以在我的 Flutter Windows 应用程序中使用云消息传递吗?我想监听应用程序中控制台的事件并使用事件数据发送 Windows 通知。

Von*_*ian 2

我已经找到了一种可用的解决方法,至少目前是这样。Allysson 的答案是作为 Dart 管理客户端发送事件,但我想在我的 Flutter Windows 应用程序上接收消息。

解决方法步骤:

  1. 首先,我们必须将 Firebase“实时数据库”添加到我们的项目中==>为此需要firebase_dartfirebase_core和/或firebase_dart_flutter包。如果我们不开发 Flutter Windows 应用程序,则不需要 flutter 包。
  2. 准备我们的数据类来处理来自 RTDB 的传入事件:
class Message {
  final String title;
  final String subtitle;
  final int id;
  final String? url;
  final String? operation;
  final String? device;

  @override
  const Message(
      {required this.title,
      required this.subtitle,
      required this.id,
      this.url,
      this.operation,
      this.device});

  @override
  String toString() {
    return 'Message{title: $title, subtitle: $subtitle, id: $id, url: $url, operation: $operation, device: $device}';
  }

  Map<String, dynamic> toMap() {
    return {
      'title': title,
      'subtitle': subtitle,
      'id': id,
      'url': url,
      'operation': operation,
      'device': device,
    };
  }

  factory Message.fromMap(Map<String, dynamic> map) {
    return Message(
      title: map['title'] as String,
      subtitle: map['subtitle'] as String,
      id: map['id'] as int,
      url: map['url'] as String?,
      operation: map['operation'] as String?,
      device: map['device'] as String?,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在此类中Message,我们有不可为 null idtitlesubtitle字段,它们是来自 RTDB 的静态数据结构。其他可为空的字段是可选的,我将对此进行解释。

  1. 在 RTDB 中定义我们的字段

实时数据库中的字段

正如已经指出的,idtitlesubtitle字段是强制性的且不可为空。id是一个唯一的整数,每次由我们的 Windows 客户端检查,您可以选择将最后一个id值保存在磁盘上,以防止应用程序重新启动时出现重复通知。每次id在我们的数据库中发生更改时,都会将事件发送到监听此 RTDB 的客户端,然后客户端检查 的id值是否是新的,然后发送通知,pub.dev 上有多个通知包。titlesubtitle传递给我们的通知包的函数来实际发送通知。

  1. 收听 RTDB 的声音

  StreamSubscription? startListening() {
    FirebaseDatabase db = FirebaseDatabase(
        app: app,
        databaseURL:
            '<Our RTDB URl>');
    db.goOnline();
    return db.reference().onValue.listen((event) async {
      final data = event.snapshot.value;
      if (data != null &&
          data['title'] != null &&
          data['subtitle'] != null &&
          data['id'] != null &&
          data['title'] != '' &&
          data['subtitle'] != '') {
        Message message = Message.fromMap(data);
        if (widget.prefs.getInt('id') != message.id) {
          if (message.device == (await deviceInfo.windowsInfo).computerName ||
              message.device == null) {
            var toast =
                LocalNotification(title: message.title, body: message.subtitle)
                  ..show();
            toast.onClick = () {
              if (message.url != null) {
                launchUrl(Uri.parse(message.url!));
              }
            };
            await widget.prefs.setInt('id', message.id);
          }
        }
      }
    });
  }
Run Code Online (Sandbox Code Playgroud)

在上面的代码示例中,我们为数据库创建一个对象,监听它并返回 StreamSubscription 来处理监听状态。

最后,我们将真正开始监听我们的数据库:

 StreamSubsricption? dbSub;
 @override
 void initState() {
    super.initState();
    dbSub = startListening(); //Start listening to our RTDB
  }
 @override
 void dispose() {
   dbSub?.cancel(); //Stop listening - Must be called to prevent a memory-leak
   super.dispose();
 }
Run Code Online (Sandbox Code Playgroud)

这样,每次id在 Firebase 控制台上更改 的值后,我们都会向 Windows 客户端发送通知,我们可以选择定义url字段,以便在客户端单击通知时在浏览器中打开 URL。