Flutter中如何获取Firebase自动生成文档ID并存入模型ID字段
如何将Firebase自动生成的文档ID存入自定义模型的ID字段?
当然可以实现,这里提供两种可靠方案,优先推荐第一种(单次写入操作,更高效):
方案一:提前生成文档ID再写入数据
Firebase允许你先创建空的文档引用(不写入数据),直接获取其自动生成的ID,之后将ID传入模型,通过set()方法写入完整数据。
修改你的addFunction代码如下:
void addFunction() async { final uid = await Provider.of<AuthProvider>(context, listen: false).getCurrentUID(); if (dateController.text.trim().isNotEmpty && timeController.text.trim().isNotEmpty && topicController.text.trim().isNotEmpty) { // 1. 生成空文档引用,获取自动生成的ID final timelineDocRef = db.collection('users').doc(uid).collection('time-line').doc(); final timelineId = timelineDocRef.id; // 2. 创建Timeline对象时传入ID,再写入Firebase await timelineDocRef.set( Timeline( id: timelineId, date: dateController.text.trim(), time: timeController.text.trim(), topic: topicController.text.trim(), isDone: false ).toJson() ); } else { ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text( 'All fields required!', style: TextStyle(fontFamily: 'poppins', fontWeight: FontWeight.w400), ) )); } Navigator.of(context).pop(); }
方案二:先写入数据,再更新ID到文档中
这种方式需要两次Firebase操作:先通过add()写入数据,再用返回的文档引用更新ID字段。虽然可行,但效率不如方案一。
示例代码:
void addFunction() async { final uid = await Provider.of<AuthProvider>(context, listen: false).getCurrentUID(); if (dateController.text.trim().isNotEmpty && timeController.text.trim().isNotEmpty && topicController.text.trim().isNotEmpty) { // 1. 先写入数据,获取文档引用 final docRef = await db.collection('users').doc(uid).collection('time-line').add( Timeline( date: dateController.text.trim(), time: timeController.text.trim(), topic: topicController.text.trim(), isDone: false ).toJson() ); // 2. 更新文档,把ID存入id字段 await docRef.update({'id': docRef.id}); } else { ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text( 'All fields required!', style: TextStyle(fontFamily: 'poppins', fontWeight: FontWeight.w400), ) )); } Navigator.of(context).pop(); }
优化模型的快照解析
你的Timeline.fromSnapshot构造函数可以优化:文档ID本身可通过snapshot.id直接获取,无需依赖存储在文档数据里的id字段(若已存储也可继续使用),这样更可靠:
Timeline.fromSnapshot(DocumentSnapshot snapshot) : id = snapshot.id, // 直接取文档自带的ID date = snapshot.data()?['date'], time = snapshot.data()?['time'], topic = snapshot.data()?['topic'], isDone = snapshot.data()?['isDone'];
后续更新数据示例
有了文档ID后,可直接用它定位文档进行更新:
void updateTimeline(String timelineId) async { final uid = await Provider.of<AuthProvider>(context, listen: false).getCurrentUID(); await db.collection('users').doc(uid).collection('time-line').doc(timelineId).update({ 'isDone': true, // 其他需要更新的字段 }); }
内容的提问来源于stack exchange,提问作者sonjuro
相关产品推荐
相关产品推荐

