Firebase Realtime - Flutter - 监听异步

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

我需要帮助,因为我需要在某个地方调用我的监听器上的 asysc,并且如果我的日期更新我的应用程序就会冻结。

我确信这是由于我对 Firestore 的调用未正确完成

late List<Data> sensorList = [];

  @override
  void initState() {
    super.initState();
    _tooltipBehavior = TooltipBehavior(enable: true);
    //_activateListerner();
    getSensorData();
  }

  void getSensorData()  {
     _database.child(_path).orderByKey().limitToLast(10).onValue.listen((data) {
      debugPrint("${data.snapshot.value}");
      final sensorData = Map<String, dynamic>.from(
          data.snapshot.value as Map<dynamic, dynamic>);
      sensorData.forEach((key, value) {
        final nextData = Data.fromRTDB(Map<String, dynamic>.from(value));
        debugPrint("${nextData.data}");
        sensorList.add(nextData);
        debugPrint("${sensorList[0].data}");
      });
      setState(() {});
    });
  }

flutter firebase firebase-realtime-database
1个回答
0
投票

您的应用程序似乎冻结了,因为数据处理和状态更新是直接在 Firestore 流的事件侦听器回调中完成的。这可能会导致性能问题,尤其是在数据更新频繁或数据处理繁重的情况下。此外,通过直接更新流侦听器内的 UI 状态 (

setState()
),您可能会触发小部件的过度重建。

为了解决这个问题,您可以使数据处理异步并确保 UI 更新顺利进行。以下是一些改进当前实施的建议:

  1. 使用异步流处理:您可能希望异步处理 Firestore 中的数据以避免阻塞主线程。这可以通过将数据处理移至单独的异步方法来完成,然后您可以从侦听器调用该方法。

  2. 批量更新:不要在收到每条数据后立即更新状态,而是考虑从流中收集数据,然后更新一次状态,从而减少重建次数。

  3. 错误处理:确保处理侦听 Firestore 流时可能发生的任何潜在错误。

这是包含这些建议的

getSensorData()
方法的更新版本:

void getSensorData() {
  _database.child(_path).orderByKey().limitToLast(10).onValue.listen(
    (data) async {
      debugPrint("${data.snapshot.value}");
      try {
        final sensorData = Map<String, dynamic>.from(
            data.snapshot.value as Map<dynamic, dynamic>);
        List<Data> newSensorList = [];
        for (var entry in sensorData.entries) {
          final nextData = Data.fromRTDB(Map<String, dynamic>.from(entry.value));
          debugPrint("${nextData.data}");
          newSensorList.add(nextData);
        }
        await Future.delayed(Duration.zero); // This line yields control to other tasks in the event queue.
        setState(() {
          sensorList.addAll(newSensorList);
        });
      } catch (e) {
        debugPrint("Error processing data: $e");
      }
    },
    onError: (error) {
      debugPrint("Error listening to data: $error");
    }
  );
}

此代码做了以下改进:

  • 它在循环内处理数据并将结果存储在本地列表中(
    newSensorList
    ),减少了调用
    setState()
    的频率。
  • 它使用
    await Future.delayed(Duration.zero);
    来让出执行,直到下一个事件循环周期,这有助于保持 UI 响应。
  • 它只在每次数据获取时更新小部件的状态一次,而不是每个数据项,从而减少了重建次数。
  • 它包括基本的错误处理,以捕获和记录数据处理或侦听阶段期间的任何错误。

确保根据应用程序架构的具体情况和

Data
类的详细信息调整实现。

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