Old_SWIFT(221012)/라이브러리이야기

Firebase Cloud Firestore Database

KataRN 2022. 3. 24. 00:51
반응형

안녕하세요. KataRN입니다.

 

오늘은 Firebase Cloud Firestore Database에 대해 알아보겠습니다.

 

공식 홈페이지에서는 다음과 같이 소개하고있습니다.

-> 모바일 앱 개발을 위한 Firebase의 최신 데이터베이스로서 실시간 데이터베이스의 성공을 바탕으로 더욱 직관적인 새로운 데이터 모델을 선보입니다.

-> 실시간 데이터베이스보다 풍부하고 빠른 쿼리와 원활한 확장성을 제공합니다.

 

Firebase에서 비슷한 서비스가 하나 더있습니다.

그건 바로 FirebaseRealtime Database입니다.

 

비슷한데 왜 두개가 있을까요? 공통점도 있지만 차이점도 있기때문에 좀더 유용한 서비스를 선택해서 사용하면됩니다.

공통점

 

차이점

 

이번 글에서는 Firebase Cloud Firestore만 다루겠습니다.

Firebase Realtime Database는 아래 글을 참고해주세요.(https://katarnios.tistory.com/50)

 

Firebase Realtime Database 다루기

안녕하세요. KataRN입니다. 오늘은 Firebase Realtime Database에 대해 알아보겠습니다. 공식 홈페이지에서는 다음과 같이 소개하고있습니다. -> NoSQL 클라우드 데이터베이스로 데이터를 저장하고 동기화

katarnios.tistory.com

 

사전작업 : 코코아팟을 이용하여 "pod 'Firebase/Firestore', pod 'FirebaseFirestoreSwift'"를 설치

https://katarnios.tistory.com/23

 

CocoaPods(코코아팟) 사용법(쉬움주의, 따라만해), Charts라이브러리 설치

안녕하세요 KataRN입니다. 오늘은 코코아팟에 대해 알려드리려고 합니다. 우선 코코아팟이란? "CocoaPods는 Swift 및 Objective-C 코코아 프로젝트의 종속성 관리자입니다. 80,000 개가 넘는 라이브러리를

katarnios.tistory.com

 

간단한 설정부터 시작해보도록하죠.

Firebase의 기본설정이 되어있으신 분들은 "더보기"버튼을 누르지 마시고 진행하시면 됩니다.

Firebase가 처음이신 분들은 바로 아래 "더보기"버튼을 눌러주세요.

 

더보기

파이어베이스 홈페이지에 들어갑시다.(https://console.firebase.google.com/project/_/authentication/users)

그 뒤는 이미지로 알려드릴게요~

 

여길 보시면 다양한 기능들이 있습니다.

오늘은 인증만 다루지만 조만간 나머지도 올리겠습니다!!! 반드시!!

 

 

자 이제 인증하기위한 프로젝트 등록은 끝났습니다.

이제 iOS앱을 추가하겠습니다.

이건 iOS뿐만 아니라 안드로이드 등 다른 것들도 추가할 수 있다는 거죠ㅎㅎ

사진 재탕이라 하급 모자이크 양해바람ㅎㅎ..

 

초기화 코드는 아래에서 말씀드릴게요. 우선넘어가세요.

 

 

Firebase Realtime Database에서는 Json파일을 올렸었는데요.

Cloud Firestore는 문서파일을 올리면 알아서 Json파일로 된다고하네요.

테스트용 문서파일 : '접기'를 눌러주세요.

더보기

//

//  CreditCardDummy.swift

//  CreditCardList

//

//  Created by Bo-Young PARK on 2021/07/13.

//

 

import Foundation

 

struct CreditCardDummy {

    static let card0 = CreditCard(id: 0, rank: 1, name: "신한카드", cardImageURL: "https://www.shinhancard.com/_ICSFiles/afieldfile/2019/04/26/190426_pc_mrlife_cardplate600x380.png", promotionDetail: PromotionDetail(companyName: "신한", period: "2023.01.07(목)~2023.01.31(토)", amount: 13, condition: "온라인 채널을 통해 이벤트 카드를 보유하고, 혜택조건을 충족하신 분", benefitCondition: "이벤트 카드로 결제한 금액이 합해서 10만원이상 결제", benefitDetail: "현금 10만원", benefitDate: "2023.03.01(월)이후"), isSelected: nil)

    static let card1 = CreditCard(id: 1, rank: 2, name: "taptap S", cardImageURL: "https://static11.samsungcard.com/wcms/scard/personal/__icsFiles/afieldfile/2019/06/12/AAP1482_s.png", promotionDetail: PromotionDetail(companyName: "삼성", period: "2023.01.07(목)~2023.01.31(토)", amount: 12, condition: "온라인 채널을 통해 이벤트 카드를 보유하고, 혜택조건을 충족하신 분", benefitCondition: "이벤트 카드로 결제한 금액이 합해서 10만원이상 결제", benefitDetail: "포인트 10만원", benefitDate: "2023.03.01(월)이후"), isSelected: nil)

    static let card2 = CreditCard(id: 2, rank: 3, name: "KB국민 톡톡", cardImageURL: "https://img1.kbcard.com/ST/img/cxc/kbcard/upload/img/product/09223.png", promotionDetail: PromotionDetail(companyName: "KB국민", period: "2023.01.07(목)~2023.01.31(토)", amount: 13, condition: "온라인 채널을 통해 대상카드를 보유하신 분", benefitCondition: "이벤트 카드로 10만원 이상 이용 ", benefitDetail: "현금 10만원", benefitDate: "2023.03.01(월)이후"), isSelected: nil)

    static let card3 = CreditCard(id: 3, rank: 4, name: "올바른 FLEX 카드", cardImageURL: "https://card.nonghyup.com/content/imgs/shopmall/pro_img/card/F10043.png", promotionDetail: PromotionDetail(companyName: "농협", period: "2023.01.07(목)~2023.01.31(토)", amount: 10, condition: "온라인 채널을 통해 이벤트 카드를 보유하고, 이벤트에 응모하신 분", benefitCondition: "이벤트 대상 카드로 누적 10만원 이상 이용", benefitDetail: "현금 10만원", benefitDate: "2023.03.01(월)이후"), isSelected: nil)

    static let card4 = CreditCard(id: 4, rank: 5, name: "신한카드 Deep Dream", cardImageURL: "https://www.shinhancard.com/pconts/images/contents/card/plate/cdCreaditBJABE3.png", promotionDetail: PromotionDetail(companyName: "신한", period: "2023.01.07(목)~2023.01.31(토)", amount: 7, condition: "해당카드 보유회원", benefitCondition: "해당 카드로 결제기간동안 합산 8만원 이상 결제", benefitDetail: "포인트 8만원", benefitDate: "2023.04.01(목)이후"), isSelected: nil)

    static let card5 = CreditCard(id: 5, rank: 6, name: "우리 카드의 정석 POINT", cardImageURL: "https://pc.wooricard.com/webcontent/cdPrdImgFileList/2020/6/30/15a0b20b-f685-4155-a9bf-5e71674ab674.png", promotionDetail: PromotionDetail(companyName: "우리", period: "2023.01.07(목)~2023.01.31(토)", amount: 4, condition: "온라인 채널을 통해 이벤트 카드를 받은 고객 중 이벤트에 응모하신 분", benefitCondition: "이벤트 카드로 결제한 금액이 합해서 10만원이상", benefitDetail: "현금 8만원", benefitDate: "2023.03.01(월)이후"), isSelected: nil)

    static let card6 = CreditCard(id: 6, rank: 7, name: "NEW 씨티 클리어 카드", cardImageURL: "https://www.citibank.co.kr/download/cms/card/master/070045_8.png", promotionDetail: PromotionDetail(companyName: "씨티", period: "2023.01.07(목)~2023.01.31(토)", amount: 7, condition: "온라인 채널을 통해 이벤트 카드를 보유하고, 혜택조건을 충족하신 분", benefitCondition: "이벤트 카드로 결제한 금액이 합해서 10만원이상 이용 (1인 1회한)", benefitDetail: "7만원 캐시백", benefitDate: "2023.03.01(월)이후"), isSelected: nil)

    static let card7 = CreditCard(id: 7, rank: 8, name: "하나 클럽SK 카드", cardImageURL: "https://www.hanacard.co.kr/ATTACH/NEW_HOMEPAGE/images/cardinfo/card_img/03496.png", promotionDetail: PromotionDetail(companyName: "하나", period: "2023.01.07(목)~2023.01.31(토)", amount: 7, condition: "참여 기간 내 응모하고 이벤트 대상 카드 이용한 손님", benefitCondition: "이벤트 카드로 합산 7만원이상 결제", benefitDetail: "현금 7만원", benefitDate: "2023.03.01(월)이후"), isSelected: nil)

    static let card8 = CreditCard(id: 8, rank: 9, name: "LIKIT FUN+", cardImageURL: "https://image.lottecard.co.kr/UploadFiles/ecenterPath/cdInfo/ecenterCdInfoP12158-A12158_nm1_v.gif", promotionDetail: PromotionDetail(companyName: "롯데", period: "2023.01.07(목)~2023.01.31(토)", amount: 5, condition: "온라인 채널을 통해 이벤트 카드를 보유한 회원 중 아래 '이벤트 참여하기'를 통해 이벤트에 응모한 회원", benefitCondition: "이벤트 카드로 합산 5만원 이상 이용 시 5만원 캐시백(1인 1회)", benefitDetail: "현금 5만원", benefitDate: "2023.09.01(금)이전"), isSelected: nil)

    static let card9 = CreditCard(id: 9, rank: 10, name: "IBK 무민", cardImageURL: "https://www.bccard.com/images/individual/card/renew/list/card_100914.png", promotionDetail: PromotionDetail(companyName: "IBK기업은행", period: "2023.01.07(목)~2023.01.31(토)", amount: 5, condition: "온라인 채널을 통해 이벤트 카드를 보유하고, 혜택조건을 충족하신 분", benefitCondition: "이벤트 카드로 결제한 금액이 합해서 10만원이상 결제", benefitDetail: "포인트 5만원", benefitDate: "2023.03.01(월)이후"), isSelected: nil)

}

 

이제 앱을 실행해주세요.

위의 파일을 앱에 넣어주세요.

 

AppDelegate에서 초기화하는거 아시죠? 그때 Collection의 기본 문서들의 경로 설정과 함께 데이터를 추가해보겠습니다.

import Firebase
import FirebaseFirestoreSwift

//AppDelegate.swift의 아래 함수에 넣어주시면됩니다.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    
    FirebaseApp.configure()
    //Firebase Firestore 초기 데이터 세팅
    let db = Firestore.firestore()
    
    db.collection("creditCardList").getDocuments { snapshot, _ in
        //collection에 creditCardList 문서가 없으면 리턴
        guard snapshot?.isEmpty == true else { return }
        let batch = db.batch()
        //collection(creditCardList)의 card0 경로 설정
        let card0Ref = db.collection("creditCardList").document("card0")
        let card1Ref = db.collection("creditCardList").document("card1")
        let card2Ref = db.collection("creditCardList").document("card2")
        let card3Ref = db.collection("creditCardList").document("card3")
        let card4Ref = db.collection("creditCardList").document("card4")
        let card5Ref = db.collection("creditCardList").document("card5")
        let card6Ref = db.collection("creditCardList").document("card6")
        let card7Ref = db.collection("creditCardList").document("card7")
        let card8Ref = db.collection("creditCardList").document("card8")
        let card9Ref = db.collection("creditCardList").document("card9")
        
        db.collection("creditCardList")
        do {
            //card0Ref에 데이터 설정
            try batch.setData(from: CreditCardDummy.card0, forDocument: card0Ref)
            try batch.setData(from: CreditCardDummy.card1, forDocument: card1Ref)
            try batch.setData(from: CreditCardDummy.card2, forDocument: card2Ref)
            try batch.setData(from: CreditCardDummy.card3, forDocument: card3Ref)
            try batch.setData(from: CreditCardDummy.card4, forDocument: card4Ref)
            try batch.setData(from: CreditCardDummy.card5, forDocument: card5Ref)
            try batch.setData(from: CreditCardDummy.card6, forDocument: card6Ref)
            try batch.setData(from: CreditCardDummy.card7, forDocument: card7Ref)
            try batch.setData(from: CreditCardDummy.card8, forDocument: card8Ref)
            try batch.setData(from: CreditCardDummy.card9, forDocument: card9Ref)
        } catch let error {
            print("Error writing city to Firestore: \(error)")
        }
        //커밋하기
        batch.commit() { err in
            if let err = err {
                print("Error writing batch \(err)")
            } else {
                print("Batch write succeeded.")
            }
        }
    }
    return true
}

 

그리고 앱을 실행시켜주시면 아래처럼 데이터가 자동으로 들어갔습니다.

 

이제 불러오기, 입력, 수정, 삭제에 대해 알아보겠습니다.

 

1. 불러오기

- addSnapshotListener 함수로 문서를 읽은 후 json 파싱을 해줍니다.

- 에러가 발생할 경우에는 nil이 되며 nil일경우 데이터를 넣지 않습니다.

import FirebaseFirestore

var creditCardList: [CreditCard] = []

var db = Firestore.firestore() //Firebase Firestore

/*Firebase Firestore 읽기*/
db.collection("creditCardList").addSnapshotListener { snapshot, error in
    guard let documents = snapshot?.documents else {
        print("Error Firestore fetching document: \(String(describing: error))")
        return
    }
    self.creditCardList = documents.compactMap { doc -> CreditCard? in
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: doc.data(), options: [])
            let creditCard = try JSONDecoder().decode(CreditCard.self, from: jsonData)
            return creditCard
        } catch let error {
            print("Error json parsing \(error)")
            return nil
        }
    }
}

 

2. 입력, 수정

1. 경로를 알고 있는 경우

- updateData를 이용하여 데이터를 추가해줍니다.(수정도 가능합니다.)

var db = Firestore.firestore() //Firebase Firestore

self.db.collection("creditCardList").document("card\(cardID)").updateData(["isSelected": true])

2. 경로를 모르는 경우

- whereField를 통해 확인합니다. (예 : "id"가 cardID와 같은 경우)

- 검색 후 getDocuments를 통해 데이터 가져옵니다.

- 검색하면 여러개의 데이터가 나올수 있기 때문에 배열로 반환합니다.

var db = Firestore.firestore() //Firebase Firestore

self.db.collection("creditCardList").whereField("id", isEqualTo: cardID).getDocuments { snapshot, error in
guard let document = snapshot?.documents.first else {
  print("Error Firestore fetching document: \(String(describing: error))")
  return
  }    
  document.reference.updateData(["isSelected": true])
}

 

3. 삭제

- 데이터를 nil로 수정하는 것과 결과는 같습니다.

 

1. 경로를 아는 경우

var db = Firestore.firestore() //Firebase Firestore

self.db.collection("creditCardList").document("card\(cardID)").delete()

2. 경로를 모르는 경우

var db = Firestore.firestore() //Firebase Firestore

self.db.collection("creditCardList").whereField("id", isEqualTo: cardID).getDocuments { snapshot, error in
  guard let document = snapshot?.documents.first else {
    print("Error Firestore fetching document: \(String(describing: error))")
    return
  }
  document.reference.delete()
}

 

Firebase Cloud Firestore Database 완료!

 

오늘도 긴글 읽어주셔서 감사합니다.

 

 

 

반응형