【发布时间】:2022-12-30 16:13:24
【问题描述】:
我已经检查了 firebase_dart 和 flutterfire 包,但它们都没有提供要使用的 firebase FirebaseMessaging 类。 有什么方法可以在我的 Flutter Windows 应用程序中使用云消息传递吗?我想从应用程序中的控制台收听事件并使用事件数据发送 Windows 通知。
【问题讨论】:
标签: windows flutter dart desktop
我已经检查了 firebase_dart 和 flutterfire 包,但它们都没有提供要使用的 firebase FirebaseMessaging 类。 有什么方法可以在我的 Flutter Windows 应用程序中使用云消息传递吗?我想从应用程序中的控制台收听事件并使用事件数据发送 Windows 通知。
【问题讨论】:
标签: windows flutter dart desktop
目前还没有对该平台的支持。可以关注本次开发进度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;
}
} }
【讨论】:
我找到了一种可用的解决方法,至少目前是这样。 Allysson 的回答是关于作为 Dart 管理客户端发送事件,但我想在我的 Flutter Windows 应用程序上接收消息。
解决步骤:
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 的静态数据结构。其他可为空的字段是可选的,我将对此进行解释。
正如已经指出的那样,id、title 和subtitle 字段是必需的且不可为空。 id 是一个唯一的整数,我们的 Windows 客户端每次都会检查它,您可以选择将最后一个 id 值保存在磁盘上,以防止在应用程序重新启动时重复通知。
每次id在我们的数据库中发生变化时,事件都会发送给监听这个RTDB的客户端,然后客户端检查id的值是否是新的,然后发送通知,pub上有多个通知包。开发者title 和subtitle 被传递给我们的通知包的函数来实际发送通知。
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。
【讨论】: