如何将flutter_datetime_picker选择的DateTime存储到Firestore?
如何将DateTime以Timestamp形式存储到Firestore
我是Flutter和Firestore新手,目前用日期选择器获取了日期和时间,但都是存成字符串形式,想知道怎么把DateTime以Timestamp格式存储到Firestore?当前的日期选择器UI代码如下:
Column( children: [ ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0)), elevation: 4.0, minimumSize: const Size(10, 10), maximumSize: const Size(368, 50), ), onPressed: () { DatePicker.showDatePicker(context, theme: const DatePickerTheme( containerHeight: 210.0, ), showTitleActions: true, minTime: DateTime(2000, 1, 1), maxTime: DateTime(2123, 12, 31), onConfirm: (date) { debugPrint('confirm $date'); _date = '${date.year} - ${date.month} - ${date.day}'; setState(() {}); }, currentTime: DateTime.now(), locale: LocaleType.en); }, child: Container( alignment: Alignment.center, height: 50.0, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Row( children: <Widget>[ Row( children: <Widget>[ const Icon( Icons.date_range, size: 20, color: Colors.blueAccent, ), Text( " $_date", style: const TextStyle( color: Colors.black, fontSize: 16), ), ], ) ], ), const Text( " Reschedule", style: TextStyle( color: Colors.lightBlue, fontWeight: FontWeight.bold, fontSize: 16), ), ], ), ), ), SizedBox( height: 20, ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0)), elevation: 4.0, minimumSize: const Size(10, 10), maximumSize: const Size(368, 50), ), onPressed: () { DatePicker.showTime12hPicker( context, theme: const DatePickerTheme( containerHeight: 210.0, ), showTitleActions: true, onConfirm: (time) { debugPrint('confirm $time'); _time = '${time.hour} : ${time.minute}'; setState(() {}); }, currentTime: DateTime.now(), locale: LocaleType.en, ); setState(() {}); }, child: Container( alignment: Alignment.center, height: 50.0, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Row( children: <Widget>[ Row( children: <Widget>[ const Icon( Icons.access_time, size: 20, color: Colors.blueAccent, ), Text( " $_time", style: const TextStyle( color: Colors.black, fontSize: 16), ), ], ) ], ), const Text( " Reschedule", style: TextStyle( color: Colors.lightBlue, fontWeight: FontWeight.bold, fontSize: 16), ), ], ), ), ), ], )
解决方法
核心思路是直接存储DateTime对象而非字符串,Firebase SDK会自动将其转换为Firestore的Timestamp类型。具体步骤如下:
修改状态变量类型
把原来存储日期/时间字符串的变量,改成存储DateTime对象:DateTime? _selectedDate; DateTime? _selectedTime;更新日期选择器的回调逻辑
不要将选中的日期转成字符串,直接保存DateTime对象:onConfirm: (date) { debugPrint('confirm $date'); _selectedDate = date; setState(() {}); },更新时间选择器的回调逻辑
同理,保存选中的时间DateTime对象:onConfirm: (time) { debugPrint('confirm $time'); _selectedTime = time; setState(() {}); },优化UI显示逻辑
显示时将DateTime对象转成字符串即可,保持原来的展示样式:// 日期显示示例 Text( _selectedDate != null ? " ${_selectedDate!.year} - ${_selectedDate!.month} - ${_selectedDate!.day}" : " Select Date", style: const TextStyle(color: Colors.black, fontSize: 16), )合并日期时间并存储到Firestore
将选中的日期和时间合并为一个完整的DateTime对象,然后直接存入Firestore:// 假设你有一个触发存储的按钮或逻辑 if (_selectedDate != null && _selectedTime != null) { final combinedDateTime = DateTime( _selectedDate!.year, _selectedDate!.month, _selectedDate!.day, _selectedTime!.hour, _selectedTime!.minute, ); // 存储到Firestore FirebaseFirestore.instance.collection('your_collection_name').add({ 'scheduled_datetime': combinedDateTime, // 自动转为Timestamp }).then((doc) { debugPrint('时间已成功存储,文档ID: ${doc.id}'); }).catchError((err) { debugPrint('存储失败: $err'); }); }
额外说明
- 读取Firestore中的Timestamp时,可直接转换为
DateTime对象:final timestamp = doc.data()!['scheduled_datetime'] as Timestamp; final dateTime = timestamp.toDate(); - 确保你的
pubspec.yaml中已添加最新版的cloud_firestore依赖。
内容的提问来源于stack exchange,提问作者Iefa
相关产品推荐
相关产品推荐

