首页 > 解决方案 > 如何从 Stream 返回列表方法?扑

问题描述

我对 Flutter 还是很陌生,我用它flutter_bloc来管理状态。在 bloc 中,我正在收听存储库方法Stream<List<UserAlert>> alerts()。在这种方法中,我在 Firebase 实时数据库节点上同时监听.onChildAdded和事件并更新本地,但是一旦更新,我就无法成功返回它,因此我在 bloc 监听器上获得了 null 值。我选择手动管理它,因为我不想在每次更改时都下载整个节点,因为它在收听. 我在两个 firebase 快照范围内都尝试过,但出现类型转换错误。我在每个范围内都尝试了,并且作为方法中的最后一件事,但仍然返回 null。我怎样才能以流的形式返回?非常感谢您的帮助。.onChildRemovedList<UserAlert> alertsNoSuchMethodError: The method 'listen' was called on null..onValuereturn alerts as Stream<List<UserAlert>>Stream.value(alerts)alerts

存储方法:

Stream<List<UserAlert>> alerts() {
    print('alerts() called');
    Stream<List<UserAlert>> alertStream;

    List<UserAlert> alerts = [];
    // Option 2  return a list manually updated by two different events: More complicated but very efficient(bandwidth), lowest data consuming = Lowest Firebase bill.
    // returns one event per node record at app start and only new afterwards

    _alertSubscription = _databaseReference.onChildAdded.listen((Event event) {
      print(' observer .childAdded: added alert is : ${event.snapshot.value}');
      UserAlert userAlert = UserAlert.fromSnapshot(event.snapshot);
      alerts.add(userAlert);
//      alertStream = Stream.value(alerts); // alerts as Stream<List<UserAlert>>;
//      return alerts;

      print(
          'observer .childAdded: alerts are: $alerts and total alerts are ${alerts.length}');
    });

    // returns one event per node removed record
    _alertSubscription =
        _databaseReference.onChildRemoved.listen((Event event) {
      print(
          'observer .childRemoved: removed alert is : ${event.snapshot.value}');
      int index = alerts.indexWhere(
          (userAlert) => userAlert.id.startsWith(event.snapshot.value['Id']));

      print('index to remove is: $index');
      alerts.removeAt(index);

//      return alerts;
      print(
          'observer .childRemoved: alerts after removing are: $alerts and total alerts are ${alerts.length}');
//      return alerts;
    });
//    yield* alertStream;
    Stream.value(alerts);
  }

集团听众:

Stream<AlertState> _mapLoadAlertToState() async* {
    _alertSubscription?.cancel();
    _alertSubscription = _alertRepository
        .alerts()
        .listen((alerts) => add(AlertsUpdated(alerts)));
////        (List<UserAlert> alerts) {
////      print('_mapLoadAlertToState() userAlterts are: $alerts');
////      add(AlertsUpdated(alerts));
//    });
  }

标签: flutterfirebase-realtime-databasestream

解决方案


您可以使用该yield语句返回一个 Stream:

Stream<AlertState> _mapLoadAlertToState() async* {
    Stream<List<UserAlert>> _stream = _alertRepository.alerts();
    await for(List<UserAlert> alerts in _stream){
        yield AlertsUpdated(alerts);
    }
}

推荐阅读