【问题标题】:Use Firebase Cloud Messaging in a Flutter Windows app在 Flutter Windows 应用程序中使用 Firebase 云消息传递
【发布时间】:2022-12-30 16:13:24
【问题描述】:

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

【问题讨论】:

    标签: windows flutter dart desktop


    【解决方案1】:

    目前还没有对该平台的支持。可以关注本次开发进度here。

    发送通知的一种方式是通过http请求(调用这个类发送通知)

    import 'dart:async';
    

    导入 'dart:convert' 显示编码,json; 将 'package:http/http.dart' 导入为 http;

    类 PostCall {

    未来 makeCall({token,nome,status}) async { const postUrl = 'https://fcm.googleapis.com/fcm/send';

    final data = {
      "notification": {"body": status, "title": name},
      "priority": "high",
      "data": {
        "click_action": "FLUTTER_NOTIFICATION_CLICK",
        "id": "1",
        "status": "done"
      },
      "to": token
    };
    final headers = {
      'content-type': 'application/json',
      'Authorization': 'key=YOUR_SERVICE_KEY_FROM_FIREBASE'
    };
    
    final response = await http.post(Uri.parse(postUrl),
        body: json.encode(data),
        encoding: Encoding.getByName('utf-8'),
        headers: headers);
    
    if (response.statusCode == 200) {
      // on success do sth
      return true;
    } else {
      // on failure do sth
      return false;
    }
    

    } }

    【讨论】:

      【解决方案2】:

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

      解决步骤:

      1. 首先,我们必须将 Firebase“实时数据库”添加到我们的项目中==> firebase_dart, firebase_core, and or firebase_dart_flutter packages are required for this matter.如果我们不开发 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?,
            );
          }
        }
        

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

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

        正如已经指出的那样,id、title 和subtitle 字段是必需的且不可为空。 id 是一个唯一的整数,我们的 Windows 客户端每次都会检查它,您可以选择将最后一个 id 值保存在磁盘上,以防止在应用程序重新启动时重复通知。 每次id在我们的数据库中发生变化时,事件都会发送给监听这个RTDB的客户端,然后客户端检查id的值是否是新的,然后发送通知,pub上有多个通知包。开发者title 和subtitle 被传递给我们的通知包的函数来实际发送通知。

        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);
                  }
                }
              }
            });
          }
        

        在上面的代码示例中,我们正在为我们的数据库创建一个对象,监听它并返回 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();
         }
        

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

      【讨论】:

        猜你喜欢
        • 2020-07-09
        • 2021-07-22
        • 2020-12-31
        • 2019-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        相关资源
        最近更新 更多