如何在可选日期时提交姓名至Cloud Firestore并解决读取问题
问题分析与解决方案
你的核心问题有两个:
- 未选择日期时未触发数据提交:当前前端逻辑仅在日期输入框有内容时才调用
sendData,未选日期的分支没有提交逻辑,导致数据根本没存入Firestore。 - 读取null日期时类型转换错误:读取数据时直接将
document['date']强转为int,但当日期为null时会抛出类型异常。
一、修复前端提交逻辑
修改isCheckedTextField方法,只要姓名不为空,无论是否选择日期都执行提交,未选日期时向sendData传入null:
void isCheckedTextField() { setState(() { if (_textController.text.isEmpty) { isFalse = true; } else { isFalse = false; DateTime? selectedDate; if (_dateController.text.isNotEmpty) { selectedDate = DateFormat.yMMMd().parse(_dateController.text); } // 无论是否选日期都提交数据 nameServices.sendData(_textController.text, selectedDate); _textController.clear(); } }); _dateController.clear(); }
同时修复dispose方法里的资源释放遗漏:
@override void dispose() { _dateController.dispose(); _textController.dispose(); // 补上该方法调用 super.dispose(); }
二、修复数据读取逻辑
在StreamBuilder的列表项构建中,先判断日期字段是否为null,再做对应处理:
itemBuilder: (context, index) { DocumentSnapshot document = snapshot.data!.docs[index]; final docName = document['name']; // 先判断date是否为null,避免类型转换异常 int? docDate = document['date']; String subtitleText; if (docDate != null) { DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(docDate); subtitleText = DateFormat.yMMMMd().format(dateTime); } else { subtitleText = "未选择日期"; } return ListTile( title: Text(docName), subtitle: Text(subtitleText), ); },
三、可选优化:Firestore字段冗余处理
如果希望Firestore中不存储null字段(减少数据冗余),可以修改sendData方法,仅当date不为null时才添加该字段:
Future sendData(String name, DateTime? date) async { try { Map<String, dynamic> data = {"name": name}; if (date != null) { data['date'] = date.millisecondsSinceEpoch; } await db.add(data); } catch (e) { print('Error sending data: $e'); } }
对应的读取逻辑需调整为判断字段是否存在:
int? docDate = document.get('date', defaultValue: null);
内容的提问来源于stack exchange,提问作者Martins
相关产品推荐
相关产品推荐

