如何在Flutter与Dart中从Firebase动态获取对应商店的子集合数据?
问题:点击商店按钮无法获取对应商店的商品
每个商店在Firebase的子集合中都有商品,点击商店按钮(ElevatedButton)时,无论点击哪个商店,始终只能获取到同一个商店的数据。



现有代码
Stores页面代码
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:user/screens/pages/pages/grid_fire.dart'; class Stores extends StatefulWidget { const Stores({super.key}); @override State<Stores> createState() => _StoresState(); } class _StoresState extends State<Stores> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: const Color.fromARGB(255, 27, 207, 186), title: const Text("Stores Near By"), actions: [ IconButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const Stores(), ), ); }, icon: const Icon(Icons.exit_to_app), ), ], ), body: StreamBuilder( stream: FirebaseFirestore .instance .collection("Stores") .snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (!snapshot.hasData) { return const Center( child: CircularProgressIndicator(), ); } return GridView.count( shrinkWrap: true, physics: const ClampingScrollPhysics(), crossAxisCount: 1, mainAxisSpacing: 3, childAspectRatio: 3, crossAxisSpacing: 1, children: snapshot.data!.docs.map((document) { return InkWell( child: SizedBox( height:200, width:double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( shadowColor: Colors.red, backgroundColor: const Color.fromARGB(255, 94, 8, 2), fixedSize: const Size(120, 34), // specify width, height shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( 20, )), padding: const EdgeInsets.all(20), //content padding inside button ), onPressed: () => Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const GridFire() ) ), child: Text( document["sname"], style: const TextStyle( fontSize: 30, fontWeight: FontWeight.w300, ), ), ), ), ); }).toList(), ); }, ), ); } }
GridFire页面代码
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:user/screens/pages/pages/stores.dart'; class GridFire extends StatefulWidget { const GridFire({super.key}); @override State<GridFire> createState() => _GridFireState(); } class _GridFireState extends State<GridFire> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.green, title: const Text("Grid View1"), actions: [ IconButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const Stores(), ), ); }, icon: const Icon(Icons.exit_to_app), ), ], ), body: StreamBuilder( stream: FirebaseFirestore .instance .collection("Stores") .doc("shop1-phone-number") .collection("items") .snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (!snapshot.hasData) { return const Center( child: CircularProgressIndicator(), ); } return GridView.count( shrinkWrap: true, physics: const ClampingScrollPhysics(), crossAxisCount: 1, mainAxisSpacing: 5, childAspectRatio: 5, crossAxisSpacing: 10, children: snapshot.data!.docs.map((document) { return GestureDetector( child: SizedBox( width: MediaQuery.of(context).size.width / 1.2, height: MediaQuery.of(context).size.height / 6, child: Text( // ignore: prefer_interpolation_to_compose_strings document['itemName'], style: const TextStyle( fontSize: 25 ),), ), ); }).toList(), ); }, ), ); } }
解决方案
问题核心:GridFire页面硬编码了固定的商店文档ID,且跳转时未传递当前点击商店的ID。
步骤1:修改GridFire组件,支持接收商店ID
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:user/screens/pages/pages/stores.dart'; class GridFire extends StatefulWidget { // 新增参数:接收商店文档ID final String storeId; const GridFire({super.key, required this.storeId}); @override State<GridFire> createState() => _GridFireState(); } class _GridFireState extends State<GridFire> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.green, title: const Text("Grid View1"), actions: [ IconButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const Stores(), ), ); }, icon: const Icon(Icons.exit_to_app), ), ], ), body: StreamBuilder( // 使用传递的storeId替代硬编码值 stream: FirebaseFirestore .instance .collection("Stores") .doc(widget.storeId) .collection("items") .snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (!snapshot.hasData) { return const Center( child: CircularProgressIndicator(), ); } return GridView.count( shrinkWrap: true, physics: const ClampingScrollPhysics(), crossAxisCount: 1, mainAxisSpacing: 5, childAspectRatio: 5, crossAxisSpacing: 10, children: snapshot.data!.docs.map((document) { return GestureDetector( child: SizedBox( width: MediaQuery.of(context).size.width / 1.2, height: MediaQuery.of(context).size.height / 6, child: Text( document['itemName'], style: const TextStyle(fontSize: 25), ), ), ); }).toList(), ); }, ), ); } }
步骤2:修改Stores页面跳转逻辑,传递商店ID
在ElevatedButton的点击事件中,传入当前商店的文档ID:
// 替换原跳转代码 onPressed: () => Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => GridFire(storeId: document.id) ) ),
修改完成后,点击不同商店按钮时,会将对应商店的ID传递给GridFire,从而加载该商店的专属商品数据。
内容的提问来源于stack exchange,提问作者Nagag Madhu
相关产品推荐
相关产品推荐

