♠♠기술 구현

파이어베이스에서 상품정보 가져오기

흑백 개발자 2024. 10. 31. 12:59
728x90

큰순서를 일단은 1. 더미데이터 만들어서 거기서 끌어온다. 2. 파이어베이스에서 조건 상관없이 일단 끌어온다

3. 나중에 조건 맞춰서 거기서 끌어온다

 

Firebase Firestore에서 데이터를 가져오는 과정과 개념에 대해 단계별로 설명드릴게요. 이 설명을 통해, Firestore 데이터를 앱에서 가져오고 사용하는 과정을 이해할 수 있을 거예요.

1. Firebase Firestore 설정 개념

먼저, Firebase Firestore는 Google의 클라우드 기반 NoSQL 데이터베이스입니다. 이 데이터베이스에 저장된 데이터를 앱에서 실시간으로 읽어오거나 업데이트할 수 있어요.

Flutter 앱이 Firestore에서 데이터를 가져오려면 Firebase Firestore를 초기화하고 연결해야 합니다. Firebase 프로젝트 설정과 firebase_core, cloud_firestore 패키지 설치가 필요하며, 이 작업은 이미 설정이 완료된 상태인 것 같아요.

2. Firebase 데이터 구조 개념

Firestore는 데이터가 Collection과 Document로 구성됩니다.

  • Collection: 여러 문서의 모음입니다. 예를 들어 products라는 컬렉션이 있다면, 모든 제품 데이터가 여기에 문서 형태로 저장됩니다.
  • Document: 개별 데이터를 저장하는 단위입니다. products 컬렉션 안에 product_1, product_2와 같은 문서가 있을 수 있습니다.

Firestore에서 데이터를 가져오기 위해선 Collection과 Document에 접근하는 경로를 알아야 해요.

3. Flutter에서 Firestore 데이터 가져오기

Flutter에서 Firestore 데이터를 가져오는 과정은 다음과 같습니다.

  1. 데이터 모델 클래스 생성
    Firestore의 데이터를 Flutter 앱에서 쉽게 다루기 위해 Firestore 문서 구조와 동일한 Model 클래스를 만들어야 합니다.
    dart
  2. 예를 들어 HistoryItem이라는 모델이 있다고 가정할게요. 이 클래스는 Firestore에 저장된 제품 데이터를 Flutter 앱에서 사용할 수 있는 객체로 변환해줍니다.
class HistoryItem {
  final String id;
  final String title;
  final String imageUrl;
  final int price;
  final int? originalPrice;
  final int? discountRate;
  final bool isBest;
  final bool isFavorite;
  final double rating;
  final int reviewCount;

  HistoryItem({
    required this.id,
    required this.title,
    required this.imageUrl,
    required this.price,
    this.originalPrice,
    this.discountRate,
    this.isBest = false,
    this.isFavorite = false,
    this.rating = 0.0,
    this.reviewCount = 0,
  });

  // Firestore에서 가져온 Map 데이터를 HistoryItem 객체로 변환하는 생성자
  factory HistoryItem.fromMap(Map<String, dynamic> map) {
    return HistoryItem(
      id: map['id'] ?? '',
      title: map['title'] ?? '',
      imageUrl: map['imageUrl'] ?? '',
      price: map['price'] ?? 0,
      originalPrice: map['originalPrice'],
      discountRate: map['discountRate'],
      isBest: map['isBest'] ?? false,
      isFavorite: map['isFavorite'] ?? false,
      rating: map['rating']?.toDouble() ?? 0.0,
      reviewCount: map['reviewCount'] ?? 0,
    );
  }
}

 

  • fromMap 메서드는 Firestore에서 데이터를 가져올 때마다 호출하여, Map<String, dynamic> 형태의 데이터를 HistoryItem 객체로 변환합니다.
  • Firestore 데이터를 가져오는 Repository 클래스 생성
  • 앱에서 Firestore와 직접 소통하는 부분을 Repository 클래스로 만들어 두면 코드 관리가 쉬워집니다. 이 Repository 클래스에서 Firestore 데이터베이스에 연결하여 데이터를 가져오는 함수를 정의합니다.

 

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:onlyveyou/models/history_item.dart';

class ProductRepository {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;

  // Firestore의 products 컬렉션에서 모든 제품 데이터를 가져오는 함수
  Future<List<HistoryItem>> fetchProductsFromFirestore() async {
    final snapshot = await _firestore.collection('products').get();
    return snapshot.docs.map((doc) => HistoryItem.fromMap(doc.data())).toList();
  }
}

 

  • fetchProductsFromFirestore 함수는 products 컬렉션의 모든 문서를 가져와서 HistoryItem 객체 리스트로 변환합니다.
  • Bloc에서 데이터 가져오기 및 상태 관리하기
  • 데이터를 가져온 후 이를 앱 화면에 반영하기 위해, Bloc을 사용해 데이터를 상태로 관리할 수 있습니다. HomeBloc에서는 LoadHomeData 이벤트가 발생할 때 Firestore에서 데이터를 가져와 상태로 저장합니다.
  •  
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:onlyveyou/models/history_item.dart';
import 'package:onlyveyou/repositories/product_repository.dart';

abstract class HomeEvent {}
class LoadHomeData extends HomeEvent {}

abstract class HomeState {}
class HomeInitial extends HomeState {}
class HomeLoading extends HomeState {}
class HomeLoaded extends HomeState {
  final List<HistoryItem> products;
  HomeLoaded({required this.products});
}
class HomeError extends HomeState {
  final String message;
  HomeError(this.message);
}

class HomeBloc extends Bloc<HomeEvent, HomeState> {
  final ProductRepository productRepository;

  HomeBloc({required this.productRepository}) : super(HomeInitial()) {
    on<LoadHomeData>((event, emit) async {
      emit(HomeLoading());
      try {
        // Repository를 통해 Firestore에서 데이터를 가져옴
        final products = await productRepository.fetchProductsFromFirestore();
        emit(HomeLoaded(products: products));
      } catch (e) {
        emit(HomeError('데이터를 불러오는데 실패했습니다.'));
      }
    });
  }
}

 

UI에서 Bloc을 사용하여 상태 반영하기

BlocBuilder를 사용하여 HomeBloc의 상태를 반영해 Firestore에서 가져온 데이터를 UI에 표시할 수 있습니다.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:onlyveyou/blocs/home/home_bloc.dart';
import 'package:onlyveyou/models/history_item.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Products')),
      body: BlocBuilder<HomeBloc, HomeState>(
        builder: (context, state) {
          if (state is HomeLoading) {
            return Center(child: CircularProgressIndicator());
          } else if (state is HomeLoaded) {
            return ListView.builder(
              itemCount: state.products.length,
              itemBuilder: (context, index) {
                final product = state.products[index];
                return ListTile(
                  title: Text(product.title),
                  subtitle: Text('${product.price}원'),
                );
              },
            );
          } else if (state is HomeError) {
            return Center(child: Text(state.message));
          }
          return Container();
        },
      ),
    );
  }
}

이제 Firestore에서 데이터를 불러와 UI에 표시하는 과정이 완료되었습니다. Firestore에서 데이터를 가져와 Bloc에 상태로 저장하고, UI에서 BlocBuilder를 통해 상태 변화를 반영할 수 있게 됩니다.

728x90