Flutter Firebase Firestore获取选中文档ID返回随机值问题
问题根因
你获取到随机无效ID的核心原因是:在详情页调用FirebaseFirestore.instance.collection(...).doc()时,如果不给doc()方法传入指定的文档ID参数,Firestore SDK会默认生成一个指向未创建的全新文档的引用,返回的自然是随机生成的、不存在于现有集合中的新ID,和你点击选中的列表项没有任何关联。
修复方案
1. 列表页读取每个文档的真实ID并传递给详情页
ListView.builder中通过data.docs[index]拿到的文档快照本身就携带真实ID属性,你之前只提取了快照内存储的业务字段,没有读取ID属性。修改列表页代码如下:
itemBuilder: (context, index){ // 拿到当前索引对应的文档快照 final currentDoc = data.docs[index]; // 读取文档内存储的业务数据 Map<String, dynamic> item = currentDoc.data() as Map<String, dynamic>; // 直接从快照属性上取真实文档ID final String realDocId = currentDoc.id; return InkWell( child: Card( child: ListTile( leading: Image.asset('assets/icons/checklist.png'), title: Text(item['listName']), subtitle: Text(item['allItems'].length.toString()) ), ), onTap: (){ // 跳转时将业务数据和真实文档ID一起传入详情页 Navigator.push( context, MaterialPageRoute( builder: (context) => DetailScreen_CheckList_V3( itemData: item, docId: realDocId ) ), ); }, ); }
2. 修改详情页构造,接收传入的ID生成正确文档引用
不要在详情页凭空调用无参doc()生成新引用,直接使用列表页传过来的真实ID即可:
class DetailScreen_CheckList_V3 extends StatefulWidget { // 接收两个入参:列表项业务数据、对应文档的真实ID final Map<String, dynamic> itemData; final String docId; const DetailScreen_CheckList_V3({ super.key, required this.itemData, required this.docId }); @override State<DetailScreen_CheckList_V3> createState() => _DetailScreen_CheckList_V3State(); } class _DetailScreen_CheckList_V3State extends State<DetailScreen_CheckList_V3> { @override Widget build(BuildContext context) { // 使用传入的真实ID生成正确的文档引用,禁止无参调用doc() DocumentReference docRef = FirebaseFirestore.instance .collection('Users') .doc(FirebaseAuth.instance.currentUser!.uid) .collection('lists') .doc(widget.docId); print('当前选中文档ID:${widget.docId}'); print('对应文档引用:$docRef'); return Scaffold( appBar: AppBar( title: const Text('Your list items'), leading: InkWell( child: const Icon(Icons.fast_rewind_outlined), onTap: (){ Navigator.pop(context); }, ), ), // 剩余页面内容按原有逻辑编写即可 ); } }
注意事项
- Firestore返回的所有文档快照对象(
QueryDocumentSnapshot/DocumentSnapshot)都自带.id属性,直接读取就能拿到对应文档的真实ID,不需要额外生成。 - 无参调用
.doc()仅适用于新建文档时需要SDK自动生成新ID的场景,读取、修改、监听已有文档时,必须给.doc()传入目标文档的真实ID,否则拿到的就是随机生成的无效新文档引用。
内容的提问来源于stack exchange,提问作者Laurent Thomas
相关产品推荐
相关产品推荐

