В настоящее время я создаю простое приложение для рецептов, которое должно иметь возможность создавать рецепты с именем, инструкциями и списком ингредиентов.
Я создал коллекцию в моем облачном пожарном хранилище под названием recipes
который содержит поля name
, instruction
. Я также создал подколлекцию в коллекции рецептов под названием ingredients
.
. В моем приложении для флаттера я получаю эти данные в 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
, я перебираю свои recipeSnapshots и сначала создаю объект Recipe
без списка ингредиентов. Затем, используя documentID моего рецепта, я извлекаю incredientSnapshots и добавляю их в список ингредиентов моего ранее созданного рецепта.
Я надеюсь найти способ создать Recipe
с именем fromSnapshot
Конструктор со всеми включенными ингредиентами.
И моя вторая цель - как мне доставить ингредиенты в подборку рецептов? Рабочий процесс в моем приложении будет выглядеть следующим образом:
- Создать новый рецепт с именем
- Добавить ингредиенты по одному
- Добавить инструкцию, как приготовить еду
Поскольку мой объект Recipe
dart содержит список ингредиентов, я в идеале ищу способ просто сохранить / обновить объект рецепта и автоматически сохранить все ингредиенты для коллекции.