카테고리 없음

장바구니 데이터베이스 연결 연결2

흑백 개발자 2024. 11. 8. 21:06
728x90

랭킹 탭의 장바구니 기능을 파이어베이스와 연동하는 과정을 단계별로 설명해드리겠습니다:

  1. 장바구니 이벤트 정의 (RankingBloc)
// ranking_bloc.dart
class AddToCart extends RankingEvent {
  final String productId;
  final String userId;
  AddToCart(this.productId, this.userId);
}

Repository에 장바구니 추가 메서드 구현

// ranking_repository.dart
class RankingRepository {
  final FirebaseFirestore _firestore;

  RankingRepository({FirebaseFirestore? firestore})
      : _firestore = firestore ?? FirebaseFirestore.instance;

  Future<void> addToCart(String productId, String userId) async {
    try {
      await _firestore.runTransaction((transaction) async {
        // 1. users 컬렉션에서 현재 유저의 문서 가져오기
        final userDoc = _firestore.collection('users').doc(userId);
        final userSnapshot = await transaction.get(userDoc);

        // 2. 현재 cartItems 배열 가져오기 (없으면 빈 배열 생성)
        List<String> cartItems = List<String>.from(
            userSnapshot.exists ? userSnapshot.get('cartItems') ?? [] : []);

        // 3. 중복 체크 후 상품 ID 추가
        if (!cartItems.contains(productId)) {
          cartItems.add(productId);

          // 4. Firestore 업데이트
          if (!userSnapshot.exists) {
            transaction.set(userDoc, {'cartItems': cartItems});
          } else {
            transaction.update(userDoc, {'cartItems': cartItems});
          }
        }
      });
    } catch (e) {
      print('Error adding to cart: $e');
      throw Exception('장바구니 추가에 실패했습니다.');
    }
  }
}

Bloc에 이벤트 핸들러 추가

// ranking_bloc.dart
class RankingBloc extends Bloc<RankingEvent, RankingState> {
  final RankingRepository rankingRepository;

  RankingBloc({required this.rankingRepository}) : super(RankingInitial()) {
    on<AddToCart>((event, emit) async {
      try {
        await rankingRepository.addToCart(event.productId, event.userId);
      } catch (e) {
        print('Error adding to cart: $e');
      }
    });
  }
}

UI에서 장바구니 버튼 구현

// ranking_card_widget.dart
GestureDetector(
  onTap: () async {
    final currentUserId = await OnlyYouSharedPreference().getCurrentUserId();
    context.read<RankingBloc>().add(
          AddToCart(product.productId, currentUserId),
        );
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('장바구니에 추가되었습니다.')),
    );
  },
  child: Icon(
    Icons.shopping_bag_outlined,
    size: 20.sp,
    color: Colors.grey,
  ),
),

파이어베이스 연동 과정 정리:

  1. 데이터 구조:
    • users 컬렉션 내 각 사용자 문서에 cartItems 배열 필드가 있음
    • cartItems는 상품 ID들의 배열로 저장됨
  2. 처리 흐름:
    • 사용자가 장바구니 아이콘 클릭
    • UI에서 AddToCart 이벤트 발생
    • RankingBloc이 이벤트 수신
    • Repository의 addToCart 메서드 호출
    • Firestore transaction으로 안전하게 데이터 업데이트
    • 사용자에게 완료 알림 표시
  3. 주요 기능:
    • 중복 추가 방지
    • Transaction을 통한 안전한 데이터 처리
    • 사용자 문서가 없는 경우도 처리
    • 에러 핸들링

이렇게 구현하면 장바구니 기능이 파이어베이스와 완벽하게 연동되어 작동하며, 장바구니 페이지에서 해당 상품들을 볼 수 있게 됩니다.

728x90