如何将数据从 Firestore 映射到列表并转换为对象数据类型
Posted
技术标签:
【中文标题】如何将数据从 Firestore 映射到列表并转换为对象数据类型【英文标题】:How to map data from Firestore to a list and convert to object data type 【发布时间】:2021-05-04 13:48:53 【问题描述】:我正在尝试将来自 firestore QueryDocumentSnapshot
类型的数据映射到自定义 Class
的 Object
但没有成功
这是我的课
class Food
String name;
int price;
String image;
Food(this.name, this.price, this.image, );
下面的示例我在本地制作数据并获取它工作正常
List<Food> foodType1Local = [
Food(
name: 'Food 1',
price: 10,
image: 'assets/food1.png',
),
Food(
name: 'Food 2',
price: 20,
image: 'assets/food2.png',
),
Food(
name: 'Food 3',
price: 30,
image: 'assets/food3.png',
),
];
List<Food> foodType2Local...
List<Food> foodType3Local...
下面的示例我在 Cloud Firestore 中制作了数据并获取它是一个问题
下面的示例我正在从 Cloud Firestore 获取数据,但我收到错误 type 'QueryDocumentSnapshot' is not a subtype of type 'Food'
List foodType1Cloud = <Food>[];
List foodType2Cloud = <Food>[];
List foodType3Cloud = <Food>[];
getFoodType1Cloud() async
QuerySnapshot snapshot = await FirebaseFirestore.instance.collection("foodType1").get();
foodType1Cloud.addAll(snapshot.docs);
foodType1Cloud.map((foodType1Data)
Food(
name: foodType1Data['name'], //cant do --> name: foodType1Data[index]['name'],
price: foodType1Data['price'], //cant do --> price: foodType1Data[index]['price'],
image: foodType1Data['image'], //cant do --> image: foodType1Data[index]['image'],
);
).toList();
getFoodType2Cloud()...
getFoodType3Cloud()...
这是代码的主体,如果我尝试从 本地数据 获取它可以正常工作,但当我从云 Firestore 获取时不起作用
//tabs of length "3"
body: TabBarView(
children: [
Container(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Column(
children: <Widget>[
buildFoodList(foodType1Local),
],
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Column(
children: <Widget>[
buildFoodList(foodType1Loca2),
],
),
),
Container...
],
),
这里是代码的主体,但如果我尝试从 cloud firestore 获取,它会显示错误 type 'QueryDocumentSnapshot' is not a subtype of type 'Food'
body: TabBarView(
children: [
Container(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Column(
children: <Widget>[
buildFoodList(foodType1Cloud),
],
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Column(
children: <Widget>[
buildFoodList(foodType2Cloud),
],
),
),
Container...
],
),
我认为buildFoodList
代码也是必要的,所以我添加了它以防万一
Widget buildFoodList(List foods)
return Expanded(
child: GridView.builder(
itemCount: foods.length,
physics: BouncingScrollPhysics(),
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.8,
mainAxisSpacing: 20,
crossAxisSpacing: 20,
),
itemBuilder: (context, index)
return FoodCard(foods[index]);
,
),
);
【问题讨论】:
【参考方案1】:snapshot.docs
返回 QuerySnapshot
中所有文档的 ann 数组,显然它不是 Food
的类型。
现在,您必须遍历文档数组并使用提供此快照的所有数据的 data
成员。使用该数据,您可以将其转换为您希望的任何类型的实例。
所以,而不是这个
foodType1Cloud.addAll(snapshot.docs);
将文档内容转换为您的自定义对象并将其添加到列表中
snapshot.docs.forEach(doc =>
Map<String, dynamic> obj = doc.data;
// convert this Map to your custom object and add it to your list
);
在flutter中,你可以使用json_serializable进行这个转换!
类似的 SO 参考 - How do you load array and object from Cloud Firestore in Flutter
【讨论】:
【参考方案2】:第 1 步:
class Employee
Employee(this.employeeID, this.employeeName, this.branch, this.designation, this.location,
this.salary,
this.reference);
double employeeID;
String employeeName;
String designation;
String branch;
String location;
double salary;
DocumentReference reference;
factory Employee.fromSnapshot(DocumentSnapshot snapshot)
Employee newEmployee = Employee.fromJson(snapshot.data());
newEmployee.reference = snapshot.reference;
return newEmployee;
factory Employee.fromJson(Map<String, dynamic> json) =>
_employeeFromJson(json);
Map<String, dynamic> toJson() => _employeeToJson(this);
@override
String toString() => 'employeeName $employeeName';
Employee _employeeFromJson(Map<String, dynamic> data)
return Employee(
data['employeeID'],
data['employeeName'],
data['branch'],
data['designation'],
data['location'],
data['salary'],
);
Map<String, dynamic> _employeeToJson(Employee instance)
return
'employeeID' : instance.employeeID,
'employeeName': instance.employeeName,
'branch': instance.branch,
'designation': instance.designation,
'location': instance.location,
'salary': instance.salary,
;
第 2 步:
传递 AsyncSnapShot 并将数据构建为列表
List<Employee> employees = [];
Future<void> buildData(AsyncSnapshot snapshot) async
if (snapshot.data.documents.length == 0)
employees = [];
employees = [];
await Future.forEach(snapshot.data.documents, (element)
employees.add(Employee.fromSnapshot(element));
);
【讨论】:
以上是关于如何将数据从 Firestore 映射到列表并转换为对象数据类型的主要内容,如果未能解决你的问题,请参考以下文章
如何将一组地图从 Firestore 映射到 recyclerView?
使用 Stream 从 FireStore 获取数据并将其映射到 Flutter 类