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); }, ); } }
요약:
- Firestore로부터 불러오는 데이터의 타입을 체크: roomStartDate와 roomEndDate가 Timestamp 또는 String일 수 있기 때문에 이를 구분하여 각각 적절하게 DateTime으로 변환했습니다.
- 기본값 처리: 만약 데이터가 없거나 올바른 형식이 아닌 경우에는 DateTime.now()를 기본값으로 설정했습니다.
이제 위 코드를 적용하면 Timestamp와 String 데이터를 모두 처리할 수 있을 것입니다.
728x90
'코딩 > ♠♠기술 구현' 카테고리의 다른 글
fcm 구독으로 방향 바꾸기 (1) | 2024.09.30 |
---|---|
functions 배포 (0) | 2024.09.28 |
알림과정 (2) | 2024.09.24 |
구글 맵 연동(mapid 오류상태) (0) | 2024.09.14 |
블록 사용해서 회원가입하면 파이어스토어에 회원정보 저장하기 (0) | 2024.09.10 |