우선 더미데이터로 했다
그 후에 연동함
나중에 좀 더 세밀히 파이어베이스 연동할 거 같다.
1. 목표 설정: Firebase Firestore와 연동하여 히스토리 데이터 표시
사용자가 본 제품(히스토리) 정보를 Firestore에서 가져와 앱의 UI에 표시하고, 사용자는 최근 본 제품과 좋아요한 제품을 구분해 볼 수 있도록 구현하는 것이 목표였습니다.
2. 데이터 모델링: Firestore의 ProductModel과 UI에서 사용될 HistoryItem 정의
- ProductModel: Firestore의 products 컬렉션에서 데이터를 가져오기 위한 모델로, 제품의 다양한 정보를 포함하고 있습니다. (productId, name, price, isBest, rating 등).
- HistoryItem: UI에 표시할 히스토리용 데이터 모델로, 제품 이미지, 이름, 가격, 좋아요 여부 등 UI에 필요한 필드만을 담고 있습니다.
class ProductModel {
final String productId;
final String name;
final List<String> productImageList;
final String price;
final int discountPercent;
final bool isBest;
final double rating;
ProductModel({ ... });
factory ProductModel.fromFirestore(DocumentSnapshot doc) { ... }
}
class HistoryItem {
final String id;
final String title;
final String imageUrl;
final int price;
final int discountRate;
final bool isBest;
final bool isFavorite;
final double rating;
HistoryItem({ ... });
// copyWith 메서드로 값 복사 및 수정 가능
HistoryItem copyWith({ ... }) { ... }
}
3. 데이터 연동: Firestore 데이터 가져오기 위한 HistoryRepository 구현
데이터를 Firestore에서 가져오는 역할은 Repository 패턴을 통해 HistoryRepository에 맡겼습니다. HistoryRepository는 ProductModel 데이터를 Firestore에서 가져온 후, UI에 표시될 HistoryItem으로 변환합니다.
class HistoryRepository {
final FirebaseFirestore _firestore;
HistoryRepository({FirebaseFirestore? firestore})
: _firestore = firestore ?? FirebaseFirestore.instance;
Future<List<HistoryItem>> fetchHistoryItems() async {
final QuerySnapshot snapshot = await _firestore.collection('products').get();
return snapshot.docs.map((doc) {
final product = ProductModel.fromFirestore(doc);
return HistoryItem(
id: product.productId,
title: product.name,
imageUrl: product.productImageList.isNotEmpty ? product.productImageList[0] : '',
price: int.parse(product.price),
discountRate: product.discountPercent,
isBest: product.isBest,
isFavorite: product.favoriteList.contains('currentUserId'),
rating: product.rating,
);
}).toList();
}
}
4. 상태 관리: HistoryBloc을 통해 데이터 로드 및 상태 관리
데이터의 로드와 상태 관리 로직은 Bloc 패턴으로 구현하여 데이터의 흐름을 명확히 했습니다. HistoryBloc은 LoadHistoryItems, ToggleFavorite 등의 이벤트를 처리하고, 이를 통해 Firestore에서 데이터를 가져와 UI에 반영합니다.
class HistoryBloc extends Bloc<HistoryEvent, HistoryState> {
final HistoryRepository _repository;
HistoryBloc({required HistoryRepository repository})
: _repository = repository,
super(HistoryState(recentItems: [], favoriteItems: [])) {
on<LoadHistoryItems>((event, emit) async {
try {
final recentItems = await _repository.fetchHistoryItems();
final favoriteItems = recentItems.where((item) => item.isFavorite).toList();
emit(HistoryState(recentItems: recentItems, favoriteItems: favoriteItems));
} catch (e) {
emit(state);
}
});
on<ToggleFavorite>((event, emit) {
final updatedRecentItems = state.recentItems.map((item) {
if (item.id == event.item.id) {
return item.copyWith(isFavorite: !item.isFavorite);
}
return item;
}).toList();
final updatedFavoriteItems = updatedRecentItems.where((item) => item.isFavorite).toList();
emit(HistoryState(recentItems: updatedRecentItems, favoriteItems: updatedFavoriteItems));
});
}
}
5. UI에서 Bloc 데이터 연결 및 MultiBlocProvider로 관리
UI에서는 MultiBlocProvider를 활용하여 HistoryBloc과 HistoryRepository를 연동했습니다. HistoryBloc을 통해 로드된 데이터는 UI의 탭에 따라 최근 본 아이템과 좋아요한 아이템으로 구분해 표시됩니다.
BlocProvider<HistoryBloc>(
create: (context) => HistoryBloc(
repository: HistoryRepository(),
),
child: HistoryScreen(),
)
6. 결론
이 프로젝트를 통해 Firebase Firestore와의 연동, Bloc을 통한 상태 관리, 그리고 Repository 패턴을 통한 데이터 계층 분리를 효율적으로 구현했습니다. 이를 통해 Firebase의 데이터를 효율적으로 불러오고, UI에 동적으로 반영할 수 있었습니다.
'코딩 > ♠♠기술 구현' 카테고리의 다른 글
개발순서 (1) | 2024.11.02 |
---|---|
좋아요 관리, 실시간?전역관리? (0) | 2024.11.01 |
파이어베이스에서 상품정보 가져오기 (0) | 2024.10.31 |
홈화면 UI 만들기 (0) | 2024.10.30 |
히스토리 화면 구현 과정 (0) | 2024.10.30 |