首页 > 解决方案 > 如何从 Firestore 获取数据作为 QuerySnaphot 与 streambuilder 作为 List 与模型?

问题描述

StreamBuilder<List<RecipeData>>

 List<RecipeData> getRecipes(QuerySnapshot snapshot) {
    return snapshot.docs.map((doc) {
      return RecipeData(
        recipeTitle: doc.data()[kRecipeTitle],
        cookingTime: doc.data()[kCookingTime],
        imgPath: doc.data()[kRecipeImage],
        ingredients: doc.data()[kIngredients],
        preparation: doc.data()[kPreparation],
        numOfLikes: doc.data()[kNumOfLikes],
        publishedDate: doc.data()[kPublishedDate],
        servings: doc.data()[kServings],
        recipeCat: doc.data()[kRecipeCat],
        recipeId: doc.id,
      );
    }).toList();
  }

  Stream<List<RecipeData>> get recipeData {
    return recipeDataCollection.snapshots().map(getRecipes);
  }

这是我的数据库文件和名为 Database 的类中的此函数,我想在流生成器中使用此流并检索 listView.builder 中的数据。

标签: firebaseflutterdartgoogle-cloud-firestore

解决方案


StreamBuilder<List<RecipeData>>(
  stream: recipeData,
  builder: (BuildContext context,
      AsyncSnapshot<List<RecipeData>> snapshot) {
    if (snapshot.hasError) return Text('Something went wrong');
    if (snapshot.connectionState == ConnectionState.waiting)
      return CircularProgressIndicator();

    if (snapshot.data.isNotEmpty) {
      return ListView.builder(
        itemCount: snapshot.data.length,
        itemBuilder: (context, i) {
          return ListTile(
            title: Text(snapshot.data[i].recipeTitle),
          );
        },
      );
    } else {
      print('No Recipes found');
      return Center(child: Text('No recipes available');
    }
  },
),

注意:您不是按照推荐的方式执行此操作。

做这样的事情:

Stream<QuerySnapshot<RecipeData>> get recipeData {
  return recipeDataCollection.withConverter<RecipeData>(
    fromFirestore: (snapshot, _) => _recipeDataFromFirestore(snapshot),
    toFirestore: (data, _) => _recipeDataToFirestore(),
  ).snapshots();
}

...
// TODO: ADD THIS TO recipeData model.
RecipeData _recipeDataFromFirestore(
    DocumentSnapshot<Map<String, dynamic>> snapshot) {
  Map<String, dynamic> json = snapshot.data();
  return RecipeData(
    recipeTitle: json[kRecipeTitle],
    cookingTime: json[kCookingTime],
    imgPath: json[kRecipeImage],
    ingredients: json[kIngredients],
    preparation: json[kPreparation],
    numOfLikes: json[kNumOfLikes],
    publishedDate: json[kPublishedDate],
    servings: json[kServings],
    recipeCat: json[kRecipeCat],
    recipeId: snapshot.id,
  );
}
Map<String, dynamic> _recipeDataToFirestore(RecipeData data) {
  return <String, dynamic>{
    'recipeTitle': data.title,
    'cookingTime': data.cookingTime,
    // TODO: .. add other properties here
  };
}

// then call your list like this:
StreamBuilder<QuerySnapshot<RecipeData>>(
  stream: recipeData,
  builder: (BuildContext context,
      AsyncSnapshot<QuerySnapshot<RecipeData>> snapshot) {
    if (snapshot.hasError) return Text('Something went wrong');
    if (snapshot.connectionState == ConnectionState.waiting)
      return CircularProgressIndicator();

    List<RecipeData> recipes =
        snapshot.data.docs.map((e) => e.data()).toList();
    return ListView.builder(
      itemCount: recipes.length,
      itemBuilder: (context, i) {
        return ListTile(
          title: Text(recipes[i].name),
        );
      },
    );
  },
),

推荐阅读