큰순서를 일단은 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 데이터를 가져오는 과정은 다음과 같습니다.
- 데이터 모델 클래스 생성
Firestore의 데이터를 Flutter 앱에서 쉽게 다루기 위해 Firestore 문서 구조와 동일한 Model 클래스를 만들어야 합니다.dart - 예를 들어 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를 통해 상태 변화를 반영할 수 있게 됩니다.
'♠♠기술 구현' 카테고리의 다른 글
좋아요 관리, 실시간?전역관리? (0) | 2024.11.01 |
---|---|
히스토리에서 파이어베이스 데이터 가져오기 (2) | 2024.10.31 |
홈화면 UI 만들기 (0) | 2024.10.30 |
히스토리 화면 구현 과정 (0) | 2024.10.30 |
스크린 유틸 적용과정 (2) | 2024.10.29 |