Android flatter-FCM:如何将背景消息存储到SQLite
我正在为我的移动应用程序构建一个通知系统,其想法是将从Firebase Cloud message接收到的前台和后台消息存储到SQLite。我已经按照这里的设置来设置我的项目 这是我的代码:Android flatter-FCM:如何将背景消息存储到SQLite,android,sqlite,flutter,firebase-cloud-messaging,Android,Sqlite,Flutter,Firebase Cloud Messaging,我正在为我的移动应用程序构建一个通知系统,其想法是将从Firebase Cloud message接收到的前台和后台消息存储到SQLite。我已经按照这里的设置来设置我的项目 这是我的代码: void initState() { super.initState(); service = MySQLService(); _firebaseMessaging.configure( onMessage: (Map<String, dynamic> me
void initState() {
super.initState();
service = MySQLService();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
service.insertItem(Item.fromMessage(message)); // It's working, here.
},
onBackgroundMessage: myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(
sound: true, badge: true, alert: true, provisional: true));
_firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) {
print("Settings registered: $settings");
});
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
print("Push Messaging token: $token");
});
}
void initState(){
super.initState();
service=MySQLService();
_firebaseMessaging.configure(
onMessage:(映射消息)异步{
打印(“onMessage:$message”);
service.insertItem(Item.fromMessage(message));//它在这里工作。
},
onBackgroundMessage:myBackgroundMessageHandler,
onLaunch:(映射消息)异步{
打印(“onLaunch:$message”);
},
onResume:(映射消息)异步{
打印(“onResume:$message”);
},
);
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(
声音:真,徽章:真,警报:真,临时:真);
_firebaseMessaging.onissettings已注册
.listen((IONotificationSettings){
打印(“已注册设置:$Settings”);
});
_firebaseMessaging.getToken().then((字符串标记){
断言(令牌!=null);
打印(“推送消息传递令牌:$token”);
});
}
以及处理背景信息的代码:
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
print("onBackground: $message");
var service = MySQLService();
await service.insertItem(Item.fromMessage(message)); // It's not working, here.
return Future<void>.value();
}
未来myBackgroundMessageHandler(映射消息)异步{
打印(“onBackground:$message”);
var service=MySQLService();
wait service.insertItem(Item.fromMessage(message));//在这里它不起作用。
返回Future.value();
}
目前,我的应用程序可以:接收前台消息并将其存储到SQLite中(通过调用service.insertItem),但由于某些原因,后台消息不会存储在SQLite中,即使它显示在设备的通知列表上
更新:这里是插入消息的代码
Future<void> insertItem(Item notification) async {
final Database db = await MyDatabase.getDatabase();
await db.insert('notification', notification.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace);
return Future<void>.value();
}
Future insertItem(项目通知)异步{
final Database db=wait MyDatabase.getDatabase();
等待db.insert('notification',notification.toMap(),
conflictAlgorithm:conflictAlgorithm.replace);
返回Future.value();
}
出于某种原因,仅当FCM消息不包含通知时(例如,是纯数据消息),才会调用onBackgroundMessage
。默认情况下,这样的消息不会触发设备上的通知
我最后做的只是发送数据消息(以便能够在后台捕获它们),并用包自己处理设备上的通知部分
// TOP-LEVEL or STATIC function to handle background messages
static Future<dynamic> onBackgroundMessage(
Map<String, dynamic> notification) async {
var msg;
if (Platform.isAndroid) {
msg = notification['data'];
} else {
msg = notification;
}
DatabaseService _dbService = DatabaseService();
msg = await _dbService.insertMessage(msg);
_showNotification(msg);
return Future<void>.value();
}
static Future _showNotification(Map<String, dynamic> msg) async {
// TODO: Use a proper channel
var platformChannelSpecificsAndroid = AndroidNotificationDetails(
'your channel id', 'your channel name', 'your channel description',
importance: Importance.Max, priority: Priority.High);
var platformChannelSpecificsIos =
IOSNotificationDetails(presentSound: true);
var platformChannelSpecifics = NotificationDetails(
platformChannelSpecificsAndroid, platformChannelSpecificsIos);
return Future.delayed(Duration.zero, () {
_flutterLocalNotificationsPlugin.show(
"some id",
msg["title"],
msg["body"],
platformChannelSpecifics,
payload: "some id",
);
});
}
//处理后台消息的顶级或静态函数
静态未来背景消息(
映射通知)异步{
var-msg;
if(Platform.isAndroid){
msg=通知['data'];
}否则{
msg=通知;
}
DatabaseService _dbService=DatabaseService();
msg=wait_dbService.insertMessage(msg);
_显示通知(msg);
返回Future.value();
}
静态未来显示通知(映射消息)异步{
//TODO:使用适当的频道
var平台ChannelSpecificSandroid=AndroidNotificationDetails(
“您的频道id”、“您的频道名称”、“您的频道描述”,
重要性:重要性。最大,优先级:优先级。高);
var平台=
IONotificationDetails(当前声音:true);
var platformChannelSpecifics=通知详细信息(
platformChannelSpecificsAndroid,platformChannelSpecificsIos);
返回未来。延迟(Duration.zero,(){
_flatterLocalNotificationsPlugin.show(
“某个id”,
msg[“标题”],
味精[“正文”],
平台通道细节,
有效载荷:“某个id”,
);
});
}
要使其正常工作,所有涉及的插件必须提前注册,如中的“默认情况下,后台消息传递未启用。要在后台处理消息”,如下所述
试图将那里写的内容翻译成kotlin项目,我最终创建了一个文件/android/app/src/main/kotlin//Application.kt,用于注册插件,如:
package <your package>
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
import com.tekartik.sqflite.SqflitePlugin
import com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin
public class Application: FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
}
override fun registerWith(registry: PluginRegistry) {
io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith(
registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"))
com.tekartik.sqflite.SqflitePlugin.registerWith(
registry.registrarFor("com.tekartik.sqflite.SqflitePlugin"))
com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.registerWith(
registry.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"))
}
}
包
导入io.flatter.app.flatterApplication
导入io.flatter.plugin.common.PluginRegistry
导入io.flatter.plugin.common.PluginRegistry.PluginRegistrantCallback
导入io.flatter.plugins.firebasemessaging.FlatterFireBaseMessagingService
导入com.tekartik.sqflite.SqflitePlugin
导入com.dexterous.flatterLocalNotifications.flatterLocalNotificationsPlugin
公共类应用程序:flatterApplication(),PluginRegistrantCallback{
重写fun onCreate(){
super.onCreate()
FlatterFireBaseMessAgingService.setPluginRegistrNet(此)
}
用(注册表:PluginRegistry)覆盖乐趣注册表{
io.flatter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith(
registry.registrrfor(“io.flatter.plugins.firebasemessaging.FirebaseMessagingPlugin”))
com.tekartik.sqflite.SqflitePlugin.registerWith(
registry.registerFor(“com.tekartik.sqflite.SqflitePlugin”))
com.dexterous.flatterLocalNotifications.flatterLocalNotificationsPlugin.registerWith(
RegistrFor(“com.dexterous.flatterLocalNotifications.flatterLocalNotificationsPlugin”))
}
}
问题出在iOS还是Android,还是两者都有?你能分享MySQLService的代码吗?也许你启动服务的方式不对?看看这个包,它假设在后台执行DB任务。我不认为我的插入函数有什么问题,因为它在前台消息的情况下工作。仅不插入背景消息。也许onBackgroundMessageHangler从一开始就没有打电话,不能确定,因为我不知道如何在后台调试。我认为即使你的应用程序关闭了,你仍然可以进行调试。例如,如果您的android手机连接到您的机器,并且在后台收到一条消息,则将执行print(“onBackground:$message”)代码>因此请检查您的ID中的日志