How to load async Stream only one time in Flutter?

眉间皱痕 提交于 2021-01-28 10:31:50

问题


I get a normal Stream of DocumentSnapshots from Firebase, and from it I generate another stream with the asyncMap() method :

    final _dataBaseReference = FirebaseFirestore.instance;

Future<Stream> getPersonalShiftsbyDay() async {
    
    //the first, normal stream 
    
     Stream firstStream =  Stream<DocumentSnapshot> _personalShifts =
            _dataBaseReference.doc("personalScheduledShift/$_empId").snapshots();
    
     // the second stream, obtained with asyncMap 
    
   return _personalShifts.asyncMap((event) async {


      _shiftDetails = {};

      await Future.forEach(event.data().keys, (key) async {
        DocumentSnapshot _shiftDoc = await _dataBaseReference
            .doc("/scheduledShift/$_busId/scheduledshift/$key")
            .get();
        DocumentSnapshot _shiftEvents = await _dataBaseReference
            .doc("/scheduledShiftEvents/$_busId/events/$key")
            .get();
        DocumentSnapshot _shiftEmployees = await _dataBaseReference
            .doc("/scheduledShiftEmployee/$_busId/employee/$key")
            .get();

          _shiftDetails["${_shiftDoc.id}"] = {
            "id": _shiftDoc.id,
            "day": _shiftDoc.data()["day"].toDate(),
            "startHour": _shiftDoc.data()["startHour"].toDate(),
            "endHour": _shiftDoc.data()["endHour"].toDate(),
            "events": _eventsId.length,
            "employees": _employeesId,
          };
        
      });
      print(_shiftDetails);
      return _shiftDetails;
    });

}

The problem is, when I use the secondStream, for example in a StreamBuilder, every time I load the screen the secondStream reloads and awaits for the code contained in asyncMap , loading for a while and making the app slower.

So my question is: How can I load the asyncMap code once (maybe even only once, when the app is started), and then reuse the Stream as a normal stream, which sends events only when the data in the db changes?


回答1:


Are you doing this?

build() {
  return StreamBuilder(stream: getPersonalShiftsbyDay(), ...);
}

You should be doing this

Stream _stream;
initState() {
  ...
  _stream = getPersonalShiftsbyDay();
}

build() {
  return StreamBuilder(stream: _stream, ...);
}

To learn more:

How to deal with unwanted widget build?

https://youtu.be/vPHxckiSmKY?t=4772



来源:https://stackoverflow.com/questions/64695992/how-to-load-async-stream-only-one-time-in-flutter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!