如何从Firestore的users集合中获取用户关联的食谱数据?
从Firestore获取用户关联的食谱详情
根据你的Firestore结构(用户集合存储食谱ID列表,独立集合存储完整食谱数据),需要分两步完成查询:先获取用户关联的食谱ID列表,再根据ID批量查询完整食谱信息。
步骤说明
- 读取当前用户文档下
colrecipes子集合中的recipeIDs数组(从截图看,该子集合下有一个文档包含此数组)
- 读取当前用户文档下
- 使用Firestore的
whereIn方法,在主colrecipe集合中查询ID属于该数组的所有文档
- 使用Firestore的
- 注意:
whereIn最多支持50个元素,若食谱ID数量超过50,需要拆分数组分批查询后合并结果
代码实现示例
body: StreamBuilder<DocumentSnapshot>( // 第一步:获取当前用户的recipeIDs列表 stream: Firestore.instance .collection('users') .document(globals.user.email) .collection('colrecipes') // 替换为你实际存储recipeIDs的文档ID .document('your-recipe-ids-doc-id') .snapshots(), builder: (context, userSnapshot) { if (!userSnapshot.hasData) { return Center(child: CircularProgressIndicator()); } // 提取recipeIDs数组,处理空数组情况 List<String> recipeIDs = List.from(userSnapshot.data['recipeIDs'] ?? []); if (recipeIDs.isEmpty) { return Center(child: Text('暂无关联食谱')); } // 第二步:根据ID列表查询主食谱集合 return StreamBuilder<QuerySnapshot>( stream: Firestore.instance .collection('colrecipe') .where(FieldPath.documentId, whereIn: recipeIDs) .snapshots(), builder: (context, recipeSnapshot) { if (!recipeSnapshot.hasData) { return Center(child: CircularProgressIndicator()); } return ListView.builder( itemCount: recipeSnapshot.data.documents.length, itemBuilder: (context, index) { final DocumentSnapshot recipeDoc = recipeSnapshot.data.documents[index]; // 构建食谱卡片(复用原有布局,替换为食谱文档数据) return Card( margin: const EdgeInsets.all(4.0), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), elevation: 20, shadowColor: Color.fromARGB(255, 0, 0, 0), child: GestureDetector( onTap: () => navigateToInfo(recipeDoc), onTapDown: (details) => _getTapPosition(details), onLongPress: () => _showContextMenu(context), child: Container( child: ClipRRect( borderRadius: BorderRadius.circular(20.0), child: Column( mainAxisSize: MainAxisSize.max, children: <Widget>[ Stack( children: <Widget>[ Container( height: MediaQuery(context).size.height * 0.17, decoration: BoxDecoration( image: DecorationImage( image: NetworkImage( '${recipeDoc["image"]}?alt=media&token', ), fit: BoxFit.cover, ), ), ), ], ), Container( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 6), height: MediaQuery(context).size.height * 0.05, width: MediaQuery(context).size.width, decoration: BoxDecoration( color: Color.fromARGB(146, 205, 204, 204), ), child: Align( alignment: Alignment.centerLeft, child: Text( recipeDoc["recipeName"], style: TextStyle( overflow: TextOverflow.clip, color: Color.fromARGB(255, 51, 44, 25), fontWeight: FontWeight.bold, fontSize: displayWidth(context) * 0.050, ), ), ), ), Container( padding: EdgeInsets.all(5), height: MediaQuery(context).size.height * 0.06, decoration: BoxDecoration( color: Color.fromARGB(255, 98, 91, 94), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Row( children: [ Transform.scale( scale: 1.4, child: Icon( Icons.room_service, color: Colors.white, ), ), SizedBox(width: 10), Text( recipeDoc["recipeServe"], style: TextStyle( fontSize: displayWidth(context) * 0.045, color: Colors.white, ), ), ], ), Row( children: [ Transform.scale( scale: 1.4, child: Icon( Icons.access_time_filled, color: Colors.white, ), ), SizedBox(width: 10), Text( recipeDoc["recipeTimePrepared"], style: TextStyle( fontSize: displayWidth(context) * 0.045, color: Colors.white, ), ), ], ) ], ), ) ], ), ), ), ), ); }, ); }, ); }, ),
额外说明
- 请替换代码中的
your-recipe-ids-doc-id为实际存储recipeIDs数组的文档ID(如果是自动生成的ID,需确认具体值) - 若
recipeIDs数量超过50,需将数组拆分为多个子数组(每个最多50个元素),分别查询后合并结果 - 原代码中
if ((recipemodel.recipeName)!.isEmpty)的判断逻辑不合理,直接使用查询到的食谱文档数据即可
内容的提问来源于stack exchange,提问作者user19402977
相关产品推荐
相关产品推荐

