Flutter签到签出页面问题:签出按钮可点击但无法写入Firebase
问题分析
你的核心问题在于:每次点击签到/签出时,代码都会调用Firestore.instance.collection('checkInOut').add()新增一条独立文档。签到时文档只有checkInTime,签出时又新建一个只有checkOutTime的文档,导致签到和签出数据分散,无法关联成完整的打卡记录。
解决方案
需要改为:签到时创建文档并保存其ID,签出时通过该ID更新同一个文档的签出时间。以下是修改后的完整代码:
class _CheckInOutState extends State<CheckInOut> { DateTime? checkInTime; DateTime? checkOutTime; bool isCheckedIn = false; String? currentDocumentId; // 新增:存储当前签到记录的文档ID String getFormattedDateTime(DateTime dateTime) { return DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime); } Future<void> saveCheckInOutTime() async { try { if (isCheckedIn) { // 签到:创建新文档并保存ID DocumentReference docRef = await FirebaseFirestore.instance.collection('checkInOut').add({ 'fileName': widget.selectedFileName, 'checkInTime': Timestamp.fromDate(DateTime.now()), 'checkOutTime': null, 'staffName': widget.staffName, }); setState(() { currentDocumentId = docRef.id; }); } else { // 签出:更新已有的签到文档 if (currentDocumentId != null) { await FirebaseFirestore.instance.collection('checkInOut').doc(currentDocumentId).update({ 'checkOutTime': Timestamp.fromDate(DateTime.now()), }); } } } catch (e) { print('Error saving check-in/out time: $e'); } } void toggleCheckInOut() async { setState(() { isCheckedIn = !isCheckedIn; if (isCheckedIn) { checkInTime = DateTime.now(); checkOutTime = null; currentDocumentId = null; // 重置文档ID,准备新的签到记录 } else { checkOutTime = DateTime.now(); } }); await saveCheckInOutTime(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Check In/Out'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ if (isCheckedIn && checkInTime != null) Text( 'Check In: ${getFormattedDateTime(checkInTime!)}', style: const TextStyle(fontSize: 18), ), if (!is(-Error_in望)泛� Rec crunch基于 Cas不再 层表达,直接保留原逻辑) Text( 'Check Out: ${getFormattedDateTime(checkOutTime!)}', style: const TextStyle(fontSize: 18), ), const SizedBox(height: 40), ElevatedButton( onPressed: isCheckedIn ? null : toggleCheckInOut, child: Text(isCheckedIn ? 'Checked In' : 'Check In'), ), const SizedBox(height: 40), ElevatedButton( onPressed: isCheckedIn ? toggleCheckInOut : null, child: Text(isCheckedIn ? 'Check Out' : 'Checked Out'), ), ], ), ), ); } }
关键改动说明
- 新增
currentDocumentId变量:用于存储当前签到记录的Firestore文档ID,确保签出时能找到对应的记录。 - 修改
saveCheckInOutTime方法:- 签到逻辑:创建文档后立即保存其ID到状态中。
- 签出逻辑:通过保存的文档ID调用
update()方法,给已有文档补充签出时间,而不是新建文档。
- 签到时重置
currentDocumentId:确保每次新的签到都会生成新的记录,不会和旧记录混淆。
内容的提问来源于stack exchange,提问作者berrykah
相关产品推荐
相关产品推荐

