Firebase 사용해보기 !!

2020. 4. 18. 05:36iOS

Firebase 란 ?!

구글에서 제공하는 모바일 및 웹 어플리케이션 개발 플랫폼입니다.

다양한 백엔드 서비스를 제공해주기 때문에 빠른 어플리케이션 개발이 가능해 집니다.

그리고 이러한 기능들을 모두(몇개빼고) 무료로 !! iOS, Android 와 웹 까지 지원해 줍니다. (대인배 갓 구글...)

그래서 !! 이번에 한번 그 사용법을 익혀보도록 해보겠습니다.

먼저 ...

1. 프로젝트보터 만들어 보겠습니다 !

Firebase 홈페이지 에 들어가 보시면 다음과 같이 나옵니다

여기서 시작하기를 누르시면 프로젝트 이름을 지정하라고 나오는데 사용하려는 Xcode 프로젝트와 이름을 맞춰주면 좋겠죠? ㅎㅎ

계속을 누르면 Firebase에서 무료로 제공하는 기능들에 대해 사용할 껀지 물어봅니다.

계속을 또 누르면 구글 애널리틱스 계정을 선택하라고 뜨는데 우선 Default 계정으로 설정해 줍니다.(아마 여러 프로젝트의 애널리틱스를 한 곳에 모아서 하나의 큰 흐름을 보게끔 해주는 것 같습니다.)

이제 만들기 버튼을 누르면 진짜 프로젝트가 생성이 됩니다.

생성이 완료되면 다음과 같이 생성되며 , 제공되는 기능들을 알아볼 수가 있습니다.

쭉 보게되면,

  1. 계정 인증
  2. DB
  3. 미디어 Storage
  4. 웹 호스팅
  5. 백엔드 코드 작성
  6. ML KIT
  7. 애널리틱스 등

의 기능을 제공하여 무료 프로젝트라도 일반적으로 서비스구성에 필요한 기능을 모두 갖추었다고 생각이 됩니다.

우선 먼저 사용해볼 기능은 DB 입니다. Firebase 는 NoSQL 데이터 베이스이며 굉장히 다양한 기능들을 소개하고 있습니다. 자세한 정보는 다음의 링크에서 확인해 볼 수 있습니다.

데이터 베이스 만들기를 누르면 다음과 같이 설정할 수 있는 창이 나옵니다.

일반적으로 클라이언트에서 데이터베이스에 접근할 수 있는 권한이 부여되어야 하기 때문에 프로덕션 모드에서는 이러한 권한을 미리 설정해 줄  수도 있고, 개발단계에서 테스트 용도로 클라이언트에서 자유롭게 읽고 쓸 수 있는 권한도 부여할 수 있습니다. 저희는 테스트이기 때문에 테스트 모드로 시작하겠습니다.

다음으로 넘어가면 Cloud Firestore의 위치를 지정할 수 있습니다. 클라우드 서버의 위치를 지정할 수 있는데, 주로 사용될 지역으로 설정해 주는 것이 좋습니다. 선택지에는 우선 유럽 전역 또는 북미 전역을 담당 할 수 있는 멀티리젼 이 있고, 그 외 각 지역마다 몇가지 위치로 지정할 수 있습니다. 

유럽 또는 미국 전역으로 설정 가능
그 외 각 지역 (한국은 없슴니다 ㅠㅠ)

따라서 다음과 같이 서버 위치를 asia-northeast1 로 설정하였습니다. 

이 서버 위치는 한번 설정하면 변경이 불가능 하다고 하니 !! 주의해주셔야 합니다. !!

자 !! 이제 드디어 데이터베이스를 생성할 수 있습니다. 

아직 남았군요 ..

이제 생성된 데이터 베이스 안에 넣고 싶은 데이터를 미리 생성해 줍니다. !! Firebase의 데이터 베이스에는 컬렉션이란 것을 생성해 주어야 합니다.

이러한 컬렉션 ID를 설정해주고 다음을 누르면..!

험난하도다 ..

컬렉션 안에 진짜로 저장할 정보들을 설정할 수 있습니다.

문서 ID는 고유한 값이어야 하며 자동으로 설정해 줄수도 있습니다. 필드에는 저장할 정보의 변수명과 타입을 지정할 수 있고, 타입에는 string, number, boolean, map, array, null, timestamp, geopoint 이 있습니다. 또한 이러한 필드를 생성하면 값은 초기화를 해주어야 합니다.

이제 데이터베이스가 생성이 되었고 프로젝트로 넘어가 봅시다 !!!!

프로젝트를 생성한 다음, 먼저 CocoaPods을 통해 firebase를 설치해주어야 합니다. !!

pod 'Firebase/Analytics'

Firebase에서 지원하는 기능에 대한 pod을 다음에서 볼수 있으니 들어가서 사용할 기능에 대한 pod을 적어 install 하시면 됩니다.

그 다음 앱에 Firebase를 추가해주는 작업이 필요합니다.

iOS 앱 추가를 눌러서 추가해 줄 수 있습니다.

다음 프로젝트의 번들 ID를 추가해서 등록을 해줍니다.

앱 등록이 되면 구성파일(plist) 파일을 추가해주고 

Firebase SDK 추가는 앞서 pod 파일을 추가해주는 작업입니다.

그 다음 AppDelegate에 다음과 같은 코드를 추가해줍니다.

import UIKit
import Firebase

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?

  func application(_ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions:
      [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    FirebaseApp.configure()
    return true
  }
}

마지막으로 해당 프로젝트를 실행시켜 서버와 연결 됐는지 확인한다.

이제 등록이 완료되었고 데이터 베이스를 사용해보도록 해보겠습니다.

제가 생성한 데이터베이스의 기능을 사용하기위해 추가적으로 Pod 을 추가해주어야 합니다. Firebase의 공식 문서에 따르면 다음과 같이 추가해 주도록 하고 있습니다.

pod 'Firebase/Core'
pod 'Firebase/Firestore'

# Optionally, include the Swift extensions if you're using Swift.
pod 'FirebaseFirestoreSwift'

 

이제 이 인스턴스를 사용하여 데이터 읽기, 추가를 해 줄 수 있습니다.

먼저 데이터 읽기를 해보겠습니다. 뷰컨에서는 앞서 Firestore의 인스턴스를 하나 생성해 줍니다.

let db: Firestore = Firestore.firestore()

그리고 데이터를 전송받을 구조체를 하나 선언해 줍니다.

struct User {
    var userName: String?
    var penaltyCount: Int?
    
    init?(dictionary: [String:Any]){
        self.userName = dictionary["userName"] as? String
        self.penaltyCount = dictionary["penalty"] as? Int
    }
}

여기서 중요한 것은 데이터베이스에서 정보를 받아올 때에는 일종의 K-V 값으로 정보를 받아온다는 것이다. 이를 스위프트 데이터 타입으로는 [String:Any] 타입으로 전해지기 때문에 Value 값은 일일히 Casting작업이 필요합니다. 따라서 firebase 예제코드 에서는 받아오는 데이터를 생성자를 통해 캐스팅 해주는 방식으로 구현해 주었습니다.

그리고 viewDidLoad 에서 이러한 데이터를 받아와 label을 변경해 주는 코드를 추가해 줍니다.

    func setData(){
        
        
        db.collection("study").getDocuments() { (querySnapshot, err) in // 생성한 컬렉션에서 모든 document 객체를 받아온다.
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {
                    print("\(document.documentID) => \(document.data())")

                        self.data = User(dictionary: document.data()) // 필요한 데이터를 저장
                    

                }
                    
                    if let user = self.data {  // label 변경
                        guard let name = user.userName else {
                            return
                        }
                        guard let penalty = user.penaltyCount else{
                            return
                        }
                        print(name)
                        print(penalty)

                        self.idLabel.text = name
                        self.penaltyLabel.text = "\(penalty)"
                    }
            }
        }

    }

이렇게 하면 뷰가 처음에 로드될 때 서버로 부터 데이터를 받아올 수 있습니다.

 

그리고 다음은 버튼을 눌러 서버에 있는 데이터를 업데이트 하도록 해주는 코드를 작성합니다.

    @IBAction func touchUpInsideAddButton(sender: UIButton){
        guard let pc = self.data?.penaltyCount else {
            return
        }
        let increaseCount = pc + 1
        
        self.data?.penaltyCount = increaseCount
        self.penaltyLabel.text = "\(increaseCount)"
        
        let docRef = db.collection("study").document("Juhyeoklee")
        
        docRef.updateData([ // 버튼을 눌러 변경한 데이터 값을 원하는 Document에 업데이트 하는 코드
            "penalty" : increaseCount
        ]) { err in
            if let err = err {
                print(err)
            } else {
                print("update")
            }
        }
    }

이렇게 데이터베이스 까지 업데이트 되는 것을 확인해 볼 수 있습니다.