Это мой код.Я объясню это шаг за шагом, чтобы вы могли преобразовать его в свой.
buildUserActions
возвращает StreamBuilder, который StreamBuilder принимает все документы, находящиеся в коллекции действий в облачном хранилище.Когда ConnectionState
равно active
или done
, если у меня есть данные, я назначаю их переменной с именем _lastActionDocuments
.
QuerySnapshot _lastActionDocuments;
Stream<String> streamOfFillActionFields;
Widget buildUserActions() {
return StreamBuilder(
initialData: _lastActionDocuments,
stream: Firestore.instance.collection('actions').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
case ConnectionState.active:
case ConnectionState.done:
if (snapshot.hasError)
return Center(child: Text('Error: ${snapshot.error}'));
if (!snapshot.hasData) return Text('No data finded!');
_lastActionDocuments = snapshot.data;
streamOfFillActionFields = fillActionFields();
return reallyBuildActions();
}
},
);
}
, тогда у меня есть функция Stream
Stream<String> fillActionFields() async* {
try {
List<ActionModel> newActionList = [];
for (DocumentSnapshot actionSnapshot in _lastActionDocuments.documents) {
var currentAction = ActionModel.fromSnapshot(actionSnapshot);
// I awaiting to get and fill all data.
await currentAction.fillAllFields();
newActionList.add(currentAction);
}
actionList = newActionList;
// what I yield is not important this case
yield 'data';
} catch (e) {
print(e);
yield 'nodata';
}
}
currentAction.fillAllFields
в основном эта функция запрашивает у firebase получение соответствующих данных для заполнения всех полей в моем объекте действия.
Future<void> fillAllFields() async {
DocumentSnapshot ownerSnapshot = await ownerRef.get();
owner = UserModel.fromSnapshot(ownerSnapshot);
DocumentSnapshot routeSnapshot = await routeRef.get();
route = RouteModel.fromSnapshot(routeSnapshot);
}
тогда у меня есть другой виджет, который возвращает StreamBuilder
.этот виджет создает реальный виджет пользовательского интерфейса (buildAllActions
) после того, как все данные поступили из справочных вызовов.
Widget reallyBuildActions() {
return StreamBuilder(
stream: streamOfFillActionFields,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
case ConnectionState.active:
case ConnectionState.done:
if (snapshot.data == 'data') {
return buildAllActions();
} else {
return Center(
child: Column(
children: <Widget>[
CircularProgressIndicator(),
Text('Data Loading...')
],
),
);
}
}
},
);
}