Flutter Cloud Firestore处理子集合

时间:2020-03-18 10:16:24

标签: firebase flutter google-cloud-firestore

当前,我正在创建一个简单的食谱应用程序,该应用程序应该能够使用名称,说明和配料列表来创建食谱。

我在我的Cloud Firestore中创建了一个名为recipes的集合,其中包含字段nameinstruction。我还在食谱集合中创建了一个名为ingredients的子集合。

在我的flutter应用程序中,我像这样在StreamBuilder中获取这些数据:

[...]
StreamBuilder<QuerySnapshot>(
      stream: _firestore.collection('recipes').snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          // While loading/no items available show a CircularProgressIndicator
          return Center(child: CircularProgressIndicator());
        } else {
          final recipesSnapshots = snapshot.data.documents;
          List<RecipeCard> recipeCards = [];
          for (var recipeSnapshot in recipesSnapshots) {
            Recipe recipe = Recipe.fromSnapshot(recipeSnapshot);

            // Retrieve all the ingredients from the subcollection and store them in the recipe object
            recipeSnapshot.reference
                .collection('ingredients')
                .getDocuments()
                .then((ingredientCollectionSnapshot) {
              final ingredientSnapshots =
                  ingredientCollectionSnapshot.documents;
              for (var ingredientSnapshot in ingredientSnapshots) {
                recipe.ingredients
                    .add(Ingredient.fromSnapshot(ingredientSnapshot));
              }
            });

            recipeCards.add(RecipeCard(recipe));
          }

          return Expanded(
              child:
                  ListView(padding: EdgeInsets.all(12), children: recipeCards));
        }
      },
    )
[...]

recipe对象的描述如下:

class Recipe {
  String documentID;
  String name;
  int calories = 0;
  String description;
  List<Ingredient> ingredients = List();

  Recipe(this.name,
      {this.calories = 500,
      this.description = '',
      this.ingredients});

  Recipe.fromSnapshot(DocumentSnapshot snapshot) {
    documentID = snapshot.documentID;
    name = snapshot.data['name'];
    description = snapshot.data['description'];
    calories = snapshot.data['calories'];
  }


  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'description': description,
      'image': image,
      'calories': calories,
    };
  }
}

还有我的Ingredients对象:

class Ingredient {
  String documentID;
  String name;
  int quantity = 0;
  String unit;

  Ingredient(this.name, this.quantity, this.unit);

  Ingredient.fromSnapshot(DocumentSnapshot snapshot) {
    documentID = snapshot.documentID;
    name = snapshot.data['name'];
    quantity = snapshot.data['quantity'];
    unit = snapshot.data['unit'];
  }

  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'quantity': quantity,
      'unit': unit,
    };
  }
}

RecipeCard只是一个简单的Card小部件,很好地列出了食谱的信息。您可以将其替换为简单的Text小部件以进行测试。

所以我对子集合的问题是,如何有效地从每个配方中获取数据。正如您在StreamBuilder的builder函数中看到的那样,我正在遍历我的recipeSnapshots并首先创建一个Recipe对象,但没有成分列表。然后,使用我食谱的documentID检索incredientSnapshots,并将它们添加到我先前创建的食谱的IngredientList中。

我希望找到一种方法,用包含所有成分的Recipe命名为construcor来创建fromSnapshot

我的第二个目标是如何将食材添加到食谱子集中? 我的应用中的工作流程为:

  1. 使用名称创建新食谱
  2. 一个个地添加配料
  3. 添加说明如何准备餐点

由于我的Recipe飞镖对象包含成分列表,所以我理想地在寻找一种方法来保护/更新配方对象并自动将所有成分安全地保存到子集合中。

0 个答案:

没有答案