Flutter Firebase 后台通知处理程序不更新数据

问题描述 投票:0回答:1

我正在开发一个 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。 我注意到一些事情,如果我重新启动我的应用程序,并打印存储在首选项中的有效负载,它会打印上次重新启动时存储的旧值。 你能帮我吗

应用程序必须在后台更改负载值

flutter firebase firebase-cloud-messaging sharedpreferences flutter-getx
1个回答
0
投票

  1. 后台处理程序限制:当您的应用程序在后台时,会触发

    _firebaseMessagingBackgroundHandler
    ,但 UI 和状态管理系统(如 GetX 或 Riverpod)可能未完全初始化。这使得直接更新有效负载等内容变得困难。

  2. 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
    ,以避免多次处理相同的数据。

© www.soinside.com 2019 - 2024. All rights reserved.