코딩/♠♠기술 구현

time stamp 변환 문제.

흑백 개발자 2024. 9. 27. 07:00
728x90

result_view_model 수정

문제는 fetchResults() 함수에서 Firestore로부터 데이터를 가져올 때, roomStartDate와 roomEndDate 필드가 Timestamp로 저장되어 있지 않은 경우 발생할 수 있습니다. 현재 코드는 Timestamp 타입으로 가정하고 데이터를 DateTime으로 변환하고 있는데, 데이터가 String 형식일 수도 있기 때문에 타입 변환 오류가 발생할 수 있습니다.

이 문제를 해결하기 위해서는 Firestore로부터 가져온 데이터가 Timestamp인지, 아니면 String인지를 먼저 체크한 다음, 각각의 경우에 맞게 DateTime으로 변환해야 합니다.

수정된 코드

아래는 해당 부분에서 Timestamp와 String 타입을 모두 처리할 수 있도록 수정된 코드입니다:

dart
코드 복사
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:up_down/src/model/room.dart'; import 'result_view_state.dart'; final resultViewModelProvider = StateNotifierProvider<ResultViewModel, ResultViewState>((ref) { return ResultViewModel(); }); class ResultViewModel extends StateNotifier<ResultViewState> { ResultViewModel() : super(const ResultViewState.loading()) { fetchResults(); } Future<void> fetchResults() async { state = const ResultViewState.loading(); try { final snapshot = await FirebaseFirestore.instance.collection('rooms').get(); final results = snapshot.docs.map((doc) { final data = doc.data(); // roomStartDate와 roomEndDate의 타입에 따라 처리 DateTime roomStartDate; DateTime roomEndDate; // roomStartDate 처리 if (data['roomStartDate'] is Timestamp) { roomStartDate = (data['roomStartDate'] as Timestamp).toDate(); } else if (data['roomStartDate'] is String) { roomStartDate = DateTime.parse(data['roomStartDate']); } else { roomStartDate = DateTime.now(); // 기본값 설정 } // roomEndDate 처리 if (data['roomEndDate'] is Timestamp) { roomEndDate = (data['roomEndDate'] as Timestamp).toDate(); } else if (data['roomEndDate'] is String) { roomEndDate = DateTime.parse(data['roomEndDate']); } else { roomEndDate = DateTime.now(); // 기본값 설정 } return VoteResultItem( id: doc.id, title: data['roomName'] ?? '', imageUrl: data['imageUrl'] ?? '', forPercentage: 0, // 초기값, 필요에 따라 수정 againstPercentage: 0, // 초기값, 필요에 따라 수정 isWinner: false, // 초기값, 필요에 따라 수정 participantCount: data['participantCount'] ?? 0, roomStartDate: roomStartDate, roomEndDate: roomEndDate, ); }).toList(); state = ResultViewState.success(results); } catch (e) { state = ResultViewState.error(e.toString()); } } Future<void> refreshResults() async { await fetchResults(); } void addNewRoom(Room room) { state.whenOrNull( success: (currentResults) { final newItem = VoteResultItem( id: room.roomId, title: room.roomName, imageUrl: room.imageUrl, forPercentage: 0, againstPercentage: 0, isWinner: false, participantCount: room.participantCount, roomStartDate: room.roomStartDate, roomEndDate: room.roomEndDate, ); state = ResultViewState.success([...currentResults, newItem]); }, ); } void updateVoteResult({ required String roomId, required int guiltyCount, required int notGuiltyCount, }) { state.whenOrNull( success: (currentResults) { final updatedResults = currentResults.map((item) { if (item.id == roomId) { final totalVotes = guiltyCount + notGuiltyCount; final forPercentage = totalVotes > 0 ? (guiltyCount / totalVotes) * 100 : 0.0; final againstPercentage = totalVotes > 0 ? (notGuiltyCount / totalVotes) * 100 : 0.0; return item.copyWith( forPercentage: forPercentage, againstPercentage: againstPercentage, isWinner: guiltyCount > notGuiltyCount, ); } return item; }).toList(); state = ResultViewState.success(updatedResults); }, ); } }

요약:

  1. Firestore로부터 불러오는 데이터의 타입을 체크: roomStartDate와 roomEndDate가 Timestamp 또는 String일 수 있기 때문에 이를 구분하여 각각 적절하게 DateTime으로 변환했습니다.
  2. 기본값 처리: 만약 데이터가 없거나 올바른 형식이 아닌 경우에는 DateTime.now()를 기본값으로 설정했습니다.

이제 위 코드를 적용하면 Timestamp와 String 데이터를 모두 처리할 수 있을 것입니다.

728x90