问题
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