我正在开发一个 flutter 出租车应用程序。该应用程序依赖于 Firebase 消息传递来侦听事件,例如骑手是否发送了乘车请求,因此驾驶员应该有一个 Firebase 通知,驾驶员应用程序会侦听它,因此当通知到来时,我会处理一个函数来获取有关该信息的信息乘车请求,例如乘客和地点,然后显示类似内容(乘客为您发送了乘车请求。接受/拒绝)。 这是监听来自 firebase 的通知的代码:
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.data['clickable'] == "1") {
if (notificationController.isInForeground.isTrue) {
showNotification(
id: Random().nextInt(999999999),
title: message.data['title'] ?? '',
body: message.data['body'] ?? '',
data: jsonEncode(message.data),
);
}
} else {
String? payload = jsonEncode(message.data);
notificationController.updatePayload(payload);
}
});
这是我处理的功能:
notificationController.payload.listen((payload) {
processNotify(payload);
});
但是当应用程序在后台运行时(应用程序不在屏幕上),我遇到了问题,我无法更新有效负载值。 这是我的 firebase 后台处理程序:
@pragma('vm:entry-point')
static Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message) async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
name: 'taxigo',
options: DefaultFirebaseOptions.currentPlatform,
);
if (message.data['clickable'] != "1") {
NotificationController notificationController = Get.find();
String? payload = jsonEncode(message.data);
notificationController.updatePayload(payload);
}
}
我尝试使用这样的共享首选项:
@pragma('vm:entry-point')
static Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message) async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
name: 'taxigo',
options: DefaultFirebaseOptions.currentPlatform,
);
if (message.data['clickable'] != "1") {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('payload', payload!);
}
}
并在此处打印值:
notificationController.payload.listen((payload) {
SharedPreferences prefs = await SharedPreferences.getInstance();
print('${prefs.getString('payload')}');
});
但它返回 null。 我注意到一些事情,如果我重新启动我的应用程序,并打印存储在首选项中的有效负载,它会打印上次重新启动时存储的旧值。 你能帮我吗
应用程序必须在后台更改负载值
后台处理程序限制:当您的应用程序在后台时,会触发
_firebaseMessagingBackgroundHandler
,但 UI 和状态管理系统(如 GetX 或 Riverpod)可能未完全初始化。这使得直接更新有效负载等内容变得困难。
SharedPreferences 行为:SharedPreferences 异步工作,当应用程序恢复时,在后台进行的更新可能不会立即反映。
您可以在后台进程期间将传入数据存储在
SharedPreferences
中,而不是尝试立即更新有效负载,然后在应用程序返回前台时检索并更新 UI 或状态。
以下是调整代码的方法:
@pragma('vm:entry-point')
static Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
name: 'taxigo',
options: DefaultFirebaseOptions.currentPlatform,
);
if (message.data['clickable'] != "1") {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? payload = jsonEncode(message.data);
await prefs.setString('payload', payload);
}
}
当您的应用程序恢复或进入前台时,您可以检查
SharedPreferences
中是否有任何存储的有效负载,然后相应地更新您的控制器或UI。
@override
void initState() {
super.initState();
// Check for payload when the app starts or resumes
_checkAndUpdatePayload();
}
void _checkAndUpdatePayload() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? storedPayload = prefs.getString('payload');
if (storedPayload != null) {
notificationController.updatePayload(storedPayload);
// Optionally clear the payload after processing
await prefs.remove('payload');
}
}
您可以保留现有的侦听器,但确保它在应用程序位于前台时检查 SharedPreferences:
notificationController.payload.listen((payload) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? storedPayload = prefs.getString('payload');
if (storedPayload != null) {
// Update or process the stored payload
processNotify(storedPayload);
// Clear the payload after processing
await prefs.remove('payload');
}
});
SharedPreferences
在后台存储负载数据。SharedPreferences
,以避免多次处理相同的数据。