코딩/♠♠기술 구현

히스토리에서 파이어베이스 데이터 가져오기

흑백 개발자 2024. 10. 31. 22:24
728x90

우선 더미데이터로 했다
그 후에 연동함

나중에 좀 더 세밀히 파이어베이스 연동할 거 같다.

 

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에 동적으로 반영할 수 있었습니다.

728x90

'코딩 > ♠♠기술 구현' 카테고리의 다른 글

개발순서  (1) 2024.11.02
좋아요 관리, 실시간?전역관리?  (0) 2024.11.01
파이어베이스에서 상품정보 가져오기  (0) 2024.10.31
홈화면 UI 만들기  (0) 2024.10.30
히스토리 화면 구현 과정  (0) 2024.10.30