后台接收数据时如何将数据保存到Hive数据库中?

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

应用程序在后台时接收 Firebase Cloud Messaging (FCM) 推送通知数据时,我在将数据保存到 Hive 时遇到问题。

我有一个静态方法来像这样设置配置单元

static Future<void> setUpHive() async {
    try {

      await Hive.initFlutter();

      if (!Hive.isBoxOpen("Box Name")) {
          await Hive.openBox("Box Name");
      }

    } catch (error) {
      print(error.toString());
    }
}

我在像这样的

setUpHive
函数中使用
main
静态方法

Future<void> main() async {

  await HiveHelper.setUpHive();

  runApp(
    MyApp(),
  );
}

当应用程序在后台时,然后它收到FCM消息,那么下面的代码将被调用。之后我尝试更改存储在 Hive 框中的数据

Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    // when receive FCM message when app is in the background, this block will be executed
    
    // set up the hive first
    await HiveHelper.setUpHive(); 

    // then I try to change the data stored in the Hive box
    final myBox = Hive.box("BOX NAME");
    myBox.put("key", 12345);
}

收到 FCM 后台数据后似乎没问题,但是当我完全关闭应用程序并再次调用

main
时,尝试打开这样的盒子时出现错误

   static Future<void> setUpHive() async {
        try {

          await Hive.initFlutter();

          if (!Hive.isBoxOpen("Box Name")) {
              await Hive.openBox("Box Name"); // Error in this line
          }

        } catch (error) {
          print(error.toString());
        }
    }

错误是:

HiveError:这不应该发生。请在 GitHub 上打开问题。 E/flutter(13142):[错误:flutter/lib/ui/ui_dart_state.cc(199)] 未处理的异常:HiveError:这不应该发生。请打开一个 GitHub 上的问题。 E/flutter (13142): #0 BinaryReaderImpl.readFrame (包:hive/src/binary/binary_reader_impl.dart:250:7) 电子/颤振

我尝试找到解决方案,并且我从这里找到了类似的问题关于在后台进程中使用Hive DB并且据说

雷西姆:

不幸的是,Hive 不支持多个开箱 隔离。这意味着您可以关闭主隔离区中的盒子, 在后台隔离中更新它并在主隔离中重新打开它 或者将数据从后台传递到主隔离区并 在那里执行更新...

我是Flutter新手,不太明白他说的是什么。请帮忙:(

flutter flutter-hive
3个回答
3
投票

您可以尝试以下代码。基本思想是将数据从后台隔离发送到主隔离。

Future<void> backgroundMessageHandler(RemoteMessage msg){
  IsolateNameServer.lookupPortByName('main_port')?.send(msg);
}

@override
void initState(){
  super.initState();

  ReceivePort receivePort = ReceivePort();
  IsolateNameServer.registerPortWithName(receivePort.sendPort,'main_port');

  receivePort.listen((message) {
    if(message is RemoteMessage){
      //TODO: save your data in hive box
    }
  }
    
}

0
投票

应用程序进入后台后,您需要关闭主隔离区中的蜂巢盒。当它发生时,您需要在后台隔离中进行 CRUD。如果您想在两个隔离之间同步数据(因为它们不共享相同的配置单元数据),那么您需要在隔离之间进行双向通信。

这是两个隔离体之间通信的示例代码。

import 'dart:io'; // for exit();
import 'dart:async';
import 'dart:isolate';

Future<SendPort> initIsolate() async {
  Completer completer = new Completer<SendPort>();
  ReceivePort isolateToMainStream = ReceivePort();

  isolateToMainStream.listen((data) {
    if (data is SendPort) {
      SendPort mainToIsolateStream = data;
      completer.complete(mainToIsolateStream);
    } else {
      print('[isolateToMainStream] $data');
    }
  });

  Isolate myIsolateInstance = await Isolate.spawn(myIsolate, isolateToMainStream.sendPort);
  return completer.future;
}

void myIsolate(SendPort isolateToMainStream) {
  ReceivePort mainToIsolateStream = ReceivePort();
  isolateToMainStream.send(mainToIsolateStream.sendPort);

  mainToIsolateStream.listen((data) {
    print('[mainToIsolateStream] $data');
    exit(0);
  });

  isolateToMainStream.send('This is from myIsolate()');
}

void main() async {
  SendPort mainToIsolateStream = await initIsolate();
  mainToIsolateStream.send('This is from main()');
}

了解更多信息,请访问 https://medium.com/@lelandzach/dart-isolate-2-way-communication-89e75d973f34


0
投票

专门针对这种情况创建了包isolated_box。 Box 已经隔离并可重复使用,您仍然可以流式传输更改。

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