簡體   English   中英

如何將 Firestore 中的 map 數據轉換為列表並轉換為 object 數據類型

[英]How to map data from Firestore to a list and convert to object data type

我正在嘗試將來自QueryDocumentSnapshot類型的Object數據轉換為自定義 Class 的Class但沒有成功

這是我的 class

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 中制作了數據並獲取它是一個問題

在此處輸入圖像描述

下面的示例我正在從雲 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...
       
     ],
   ),

這里是代碼的主體,但是如果我嘗試從存儲中獲取它會顯示錯誤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]);
        },
      ),
    );
  }

snapshot.docs返回QuerySnapshot中所有文檔的數組,顯然它不是Food的類型。

現在,您必須遍歷文檔數組並使用提供此快照所有數據的data成員。 使用該數據,您可以將其轉換為您希望的任何類型的實例。

所以,而不是這個

foodType1Cloud.addAll(snapshot.docs);

將文檔內容轉換為您的自定義 object 並將其添加到列表中

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 ref - 如何從 Flutter 中的 Cloud Firestore 加載數組和 object

步驟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));
    });
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM