嗨,我想将快照从实时数据库反序列化到 Company 对象,并将其添加到 _companies 列表中。 但是我一直遇到错误...
这是我到目前为止所拥有的:
List<Company> _companies = [];
@override
void initState() {
// TODO: implement initState
super.initState();
getItems().then((list){
print("Now the list is here");
setState(() {
for (int i=0; i < list.length; i++) {
Map<String, dynamic> map = list[i];
Company company = new Company.fromMap(map);
_companies.add(company);
}
});
});
}
static Future<List> getItems( ) async {
Completer<List> completer = new Completer<List>();
FirebaseDatabase.instance
.reference()
.child("Companies")
.once()
.then( (DataSnapshot snapshot) {
List map = snapshot.value; //It fails here
completer.complete(map);
} );
return completer.future;
}
这是我的公司课程:
class Company {
String key;
String category;
String company_name;
String company_url;
String country;
String description;
String email;
String faq_url;
String instagram_url;
String logo_url_image;
String p_category;
String parent_company_ok;
String timestamp;
Company();
Company.fromSnapshot(DataSnapshot snapshot)
: key = snapshot.key,
category = snapshot.value['category'],
company_name = snapshot.value['company_name'],
company_url = snapshot.value['company_url'],
country = snapshot.value['country'],
description= snapshot.value['description'],
email = snapshot.value['email'],
faq_url = snapshot.value['faq_url'],
instagram_url = snapshot.value['instagram_url'],
logo_url_image = snapshot.value['logo_url_image'],
p_category = snapshot.value['p_category'],
parent_company_ok = snapshot.value['parent_company_ok'],
timestamp = snapshot.value['timestamp'];
}
但是,它在List map = snapshot.value;
的 getItems()中失败。带有例外:_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'List<dynamic>'
如果任何人都可以提供用于在列表小部件中显示孩子的代码,我将非常高兴:)
这是我在Firebase实时数据库中的数据结构:
答案 0 :(得分:1)
snapshot.value返回一个Map,并且您正在使用List来存储它。也许这里最简单的解决方案是使用var类型来声明您的map变量:
var map = snapshot.value;
,但是最好在变量中设置类型。因此,在这种情况下,最好的选择是这样设置:
Map<dynamic, dynamic> map = snapshot.value;
查看dart文档,以提高您使用地图和列表的技巧以及它们的工作方式Lists docs Maps docs
答案 1 :(得分:1)
因为错误消息显示snapshot.value不是List,而是一个映射,所以行 List map = snapshot.value; 将始终失败。由于您正在从数据库中读取“公司”节点树,因此这将返回一个地图地图,类似于Map<String, Map<dynamic,dynamic>>
,其中包含来自相应节点的所有数据。我将为您提供一个分析Company对象中的Json数据的函数,并在源代码中留下一些注释以尝试向您解释该过程。很简单。
List<Company> _parseData(DataSnapshot dataSnapshot) {
List<Company> companyList =new List();
// here you replace List map = snapshot.value with...
Map<String, dynamic> mapOfMaps = Map.from( dataSnapshot.value );
//actually dynamic here is another Map, String are the keys like -LXuQmyuF7E... or LXuSkMdJX...
//of your picture example and dynamic other Map
//in next lines we will interate in all values of your map
//remeber that the values are maps too, values has one map for each company.
//The values are Map<String, dynamic>
//in this case String are keys like category, company_name, country, etc...
//and dynamics data like string, int, float, etc
//parsing and adding each Company object to list
mapOfMaps.values.forEach( (value) {
companyList.add(
//here you'll not use fromSnapshot to parse data,
//i thing you got why we're not using fromSnapshot
Company.fromJson( Map.from(value) )
);
});
return companyList;
}
请注意,当您从以下位置读取特定公司时,将使用Company.fromSnapshot(snapshot) 您的数据库,类似...
// just to illustrate
var snapshot = await FirebaseDatabase.instance
.reference()
.child("Companies")
.child(companyId).once();
Company.fromSnapshot( snapshot );
因为在这种情况下,snapshot.value是单个映射。 好吧,另一件事是,在您的statefull小部件中查看您的initState方法,我不知道这是否是一个好方法。 即使在执行Future之后,方法也会在initState方法内调用setState。这只是一个建议。