【发布时间】:2020-11-03 08:49:16
【问题描述】:
你能帮帮我吗?我需要将来自云火库的数据加载到 List 中,并且在颤振运行 build() 方法之前我需要它。这个想法是让这个列表准备好使用来自 StreamBuilder 的值。在下一张图片中,我解释了我想要解决的问题:
视觉小工具:https://i.stack.imgur.com/fv0eg.jpg
现在我使用 Futures 从 Cloud Firestore 请求品牌,它可以工作,但我使用异步方法,所以当我准备好列表时,小部件已经呈现,我无法在列表中搜索,因为 StreamBuilder 时为空解决。我知道我可以向 StreamBuilder 的构建者请求特定品牌的数据,但我认为有更好的方法可以做到这一点,因为品牌集合不会改变,我必须在每个 StreamBuilder 事件中请求品牌数据,它可以工作,但我对那个解决方案感觉不太好。因此,如果我能在开始时获得一个列表,我就可以保存许多从 Cloud Firestore 获取品牌数据的请求。
代码小部件:
class _GeneralInventoryPageState extends State<GeneralInventoryPage> {
ServiceFirestore _serviceFirestore = new ServiceFirestore();
static final _appResources = new AppResources();
Stream<QuerySnapshot> _streamGenericProducts; // STREAM OF PRODUCTS OF CLOUD FIRESTORE
List<MapMarca> _allBrands; // THIS IS THE LIST I WANT TO FILL WITH BRANDS OF CLOUD FIRESTORE
@override
void initState() {
super.initState();
final productCollectionName = _appResources.getResource("productCollectionName");
_streamGenericProducts = _serviceFirestore.serviceGetCollection(productCollectionName); // initialize Stream
_allBrands = new List<MapMarca>(); //initialize List<brand>
_getAllBrands();
}
void _getAllBrands() async {
var marcasRaw = await _serviceFirestore.serviceGetUniqueDocumentByCollectionName(collectionName, documentId);
if(marcasRaw == null){
print("Error");
}
else{
ModelMarca marcas = ModelMarca.fromMap(Map<String, dynamic>.from(marcasRaw)); //decoding brands
this._allBrands = marcas.listBrand; // set the List<brand>
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Inventario')
),
body: Container(
child: StreamBuilder(
stream: this._streamGenericProducts,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
else {
List<ModelProduct> genericProductList = [];
QuerySnapshot querySnapshot = snapshot.data;
querySnapshot.documents.forEach((doc){
final genericProduct = ModelProduct.fromMap(Map<String,dynamic>.from(doc.data));
genericProduct.strIdRecord = doc.documentID;
genericProductList.add(genericProduct);
});
return createProductListView(context, genericProductList);
}
},
)
),
);
}
//I use createProductListView to Create every product section detail (this method is not important)
Widget createProductListView(BuildContext context, List<ModelProduct> genericProductList) {
return ListView(
children: List<Widget>.from(genericProductList.map((genericProducto)=>createProductListTile(context,genericProducto)).toList())
);
}
// Here I build every single Product Detail, I simplify the code, please look how I get the Brand Name
Widget createProductListTile(BuildContext context, ModelProduct genericProduct) {
return Column(
children: <Widget>[
ListTile(
title: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
//code for getting the product image
),
]
),
// some code about product info....
Row(
children: <Widget>[
Expanded(child: Text("Marca: ${_getBrandName(brandCode: genericProduct.strProductBrand)}")) //HERE I ALWAYS GET "NO BRAND INFO "
],
),
// some code about product info...
],
),
),
],
);
}
String _getBrandName({String brandCode}) {
MapMarca marca = _searchBrand(brandId: brandCode);
if(marca == null) {
return "NO BRAND INFO"; // this is what is get when I run my app in the Brand Field
}
else {
return marca.valor;
}
}
}
【问题讨论】:
标签: firebase flutter google-cloud-firestore future