繁体   English   中英

Firebase:从后台消息更新model

[英]Firebase: Update model from background message

当我的应用程序在后台从我们的服务器收到一条包含数据 object 的消息时,我将如何实现我的 model 的新 state? FirebaseMessaging.onBackgroundMessage()正在运行,我可以看到从服务器发送的数据,但我不知道如何用这个新数据更新 model。 将它分配给一个变量是有效的,但稍后读取这个变量会返回 null。我也在使用 GetIt,但当应用程序在后台时无法调用它。 所有教程都只展示了如何接收数据(并将其打印到控制台),但没有展示如何在应用程序处于后台时实际使用它。

编辑:我检查了多个描述云消息传递的来源,例如https://firebase.flutter.dev/docs/messaging/usage/ 他们中的大多数只是描述如何接收消息。 例子:

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  print("Handling a background message: ${message.messageId}");
}

我已经走到这一步了。 我来自服务器的消息包含数据 object,它具有所需的 model 值(例如: "newBalance": 100.00 )。 但是,如何在后台使用此新数据更新我的应用程序中的 model? 我似乎无法访问它(如上所述,分配的变量稍后返回 null)。

经过将近一周的尝试,我想我找到了解决问题的方法。 使用hive package 应用程序将新数据写入本地数据库。 但是,当应用程序处于后台时,调用Hive.initFlutter()不起作用。 所以我在main()方法中将目录路径(await getApplicationDocumentsDirectory()).path写入SharedPreferences 然后,当应用程序在后台收到消息时,我调用

if (Platform.isAndroid) {
  SharedPreferencesAndroid.registerWith();
} else if (Platform.isIOS) {
  SharedPreferencesIOS.registerWith();
}

(来自包shared_preferences_androidshared_preferences_ios )然后我可以检索路径var dir = (await SharedPreferences.getInstance()).getString("keyForDir"); 对于 Hive。使用Hive.init(dir)我可以打开框以在那里写入我的数据(之后box.close() )。 最后,当应用程序再次位于前台时,我可以从 Hive 读取数据(之后不要忘记box.close() )。

ew,多么糟糕的解决方案,但它是唯一对我有用的解决方案。 inte.net 上的其他一些人似乎也有同样的问题( https://github.com/flutter/flutter/issues/98473 ),其他一些解决方案对他们有用,但对我不起作用。

正如文档所述,您的选择是有限的:

由于处理程序在您的应用程序上下文之外独立运行,因此无法更新应用程序 state 或执行任何影响 UI 的逻辑。 但是,您可以执行 HTTP 请求等逻辑,执行 IO 操作(例如更新本地存储),与其他插件通信等。

例如,您可以使用共享首选项插件来保存从后台消息处理程序接收到的数据,例如:

import 'package:shared_preferences/shared_preferences.dart';

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    final sharedPrefs = await SharedPreferences.getInstance();
    sharedPrefs.setString('data', <YOUR DATA FROM MESSAGE>);
}

由于此时你的应用程序在后台,所以你需要在恢复后取这个值。 在此处查看完整示例,但基本上您的主小部件中需要这样的东西:

@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
  if (state == AppLifecycleState.resumed) {
    final sharedPrefs = await SharedPreferences.getInstance();
    final data = sharedPrefs.getString('data');
    print('Found in SharedPrefs: $data');
  }
}

在此之后,您可以找到一种方法来更新您需要的任何内容,这些内容已经在您的应用程序的上下文中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM