[iOS, Firebase] 파이어 베이스 기초 활용법
Updated:
파이어베이스란?
-
관계형 데이터베이스가 아닌 NoSQL 데이터베이스 기반의 클라우드 서비스를 제공하는 플랫폼
-
인증, 푸시 알림 등의 다양한 기능을 가진 가진 라이브러리를 제공
파이어베이스 라이브러리
파이어베이스에는 다양한 기능의 API 함수들을 사용할 수 있게 해주는 많은 라이브러리를 제공한다. 그 중에서 앱을 만든다면 필수라고 생각되는 단 세개의 라이브러리의 소개와 활용법을 소개하고자 한다.
-
FirebaseAuth : 인증
-
FirebaseFirestore : 데이터 저장
-
FirebaseStorage : 파일 저장소
FirebaseAuth 라이브러리
사용자 인증기능을 사용할 수 있게 해주는 라이브러리이다. 가입에서부터 로그인까지 폭넓은 인증에 관한 API 함수를 제공한다. 이메일을 가장 기본으로 계정을 생성하며, 흔히 사용되는 API 함수는 다음과 같다.
-
가입: Auth.auth().createUser(withEmail:password:completion:)
-
로그인: Auth.auth().signIn(withEmail:password:completion:)
-
로그아웃: Auth.auth().signOut()
우선 이 포스팅에서는 이메일로 회원관리를 하는 코드들을 선보일 것이기에 다음과 같은 설정이 되어있어야 한다.
사전에 사용 예를 보이기 전에 register, login, logout 메서드는 AuthViewController 에서 다뤄지고 있는 걸로 하겠다.
class AuthViewController {
var userSession: FirebaseAuth.User? // 파이어베이스 유저 객체
var currentUser: User? // 유저 모델
static let shared = AuthViewController()
init() {
userSession = Auth.auth().currentUser // 파이어베이스의 유저 정보를 가져옴(로그인 되있는 상태가 아니면 nil)
}
.
.
.
가입
Auth.auth().createUser(withEmail:password:completion:)
func register(withEmail email: String, password: String) {
Auth.auth().createUser(withEmail: email, password: password) { result, error in
if let error = error { // 로그인 실패시 메시지 출력
print("DEBUG: \(error.localizedDescription)")
return
}
/*
추가 코드, 밑에서 FirebaseFirestore 다룰때 추가함
*/
}
}
회원가입에 성공하게 되면 파이어베이스 유저 계정 목록에 하나하나 추가가 된다. 물론 비밀번호는 표시되지 않는다.
로그인
Auth.auth().signIn(withEmail:password:completion:)
파이어베이스 사용자 계정에 등록된 유저라면 로그인 할 수 있다.
func login(withEmail email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { result, error in
if let error = error { // 로그인 실패시 메시지 출력
print("DEBUG: \(error.localizedDescription)")
return
}
.
.
.
}
}
로그아웃
Auth.auth().signOut()
func logout() {
try? Auth.auth().signOut()
}
FirebaseFirestore 라이브러리
데이터를 파이어베이스 NoSql 데이터베이스에 저장하거나 혹은 데이터베이스로부터 데이터를 가져올 수 있는 API 함수들을 제공한다. 해당 API 함수들을 사용하려면 파이어베이스에서 데이터가 어떤 구조로 저장되는지 이해해야 한다.
-
collection: document(문서)들을 가진다
-
document: 필드들을 가지며, 새로운 collection을 가질 수 있다.
-
필드: 데이터
사진으로 보도록 하자
위처럼 계속해서 컬렉션과 도큐먼트, 필드 데이터를 추가해줄 수 있다. 여기서 눈여겨 봐야 할것은 저 Document ID 이다. 이 Document ID는 임의로 우리가 지정해 줄 수 있고 지정하지 않고 파이어베이스에서 알아서 생성하게 할 수도 있다. 이 두 차이점은 아래에서 다루도록 하겠다. 구조를 대강 어느 정도 봤으니 FirebaseFirestore 라이브러리에서 자주 사용하는 API 들을 정리하자면 다음과 같다.
-
하나의 데이터 저장_1: Firestore.firestore().collection({컬렉션 이름}).document({DocumentID}).setData(_:completion:)
-
하나의 데이터 저장_2: Firestroe.firestore().collection({컬렉션 이름}).addDocument(data:completion:)
-
하나의 데이터 가져오기: Firestore.firestore().collection({컬렉션 이름}).document({documentID}).getDocument(completion:)
-
모든 데이터 가져오기: Firestore.firestore().collection({컬렉션 이름}).getDocuments(completion:)
이제 위에서 작성했던 register 함수를 확장시켜 보자.
하나의 데이터 저장_1, 하나의 데이터 가져오기
-
하나의 데이터 저장_1: Firestore.firestore().collection({컬렉션 이름}).document({DocumentID}).setData(_:completion:)
-
하나의 데이터 가져오기: Firestore.firestore().collection({컬렉션 이름}).document({documentID}).getDocument(completion:)
-
회원가입을 하게 되면 그 사용자에 대한 UID가 생성된다. 그리고 이 UID는 그 사용자 정보를 데이터베이스에 저장할 때 DocumentID로 지정하여 통일성 및 유일성을 줘야한다.
func register(withEmail email: String, password: String, username: String, fullname: String) {
Auth.auth().createUser(withEmail: email, password: password) { result, error in
if let error = error {
print("DEBUG: \(error.localizedDescription)")
return
}
guard let user = result?.user else { return } // 파이어베이스 유저 객체를 가져옴
// 전달할 데이터
let data = ["email": email,
"username": username,
"fullname": fullname
]
// 가입에 성공하면 그 유저의 uid를 파이어베이스가 생성해준다.
// 그렇기 때문에 이 uid를 기준으로 특정한 유저 데이터를 저장해야 한다.
Firestore.firestore().collection("user").document(user.uid).setData(data) { error in
if let error = error {
print("DEBUG: \(error.localizedDescription)")
return
}
self.userSession = user // 가입하면 바로 로그인 되도록 세션 등록
Firestore.firestore().collection("user").document(user.uid).getDocument { snapshot, error in
guard let userData = try? snapshot?.data(as: User.self) else { return } // 매핑(FirebaseFirestoreSwift 라이브러리를 추가해야 사용가능)
self.currentUser = userData
}
}
}
}
하나의 데이터 저장_2
Firestroe.firestore().collection({컬렉션 이름}).addDocument(data:completion:)
회원가입으로 인해 자동으로 이미 생성된 사용자 UID 를 기준으로 documentID를 지정해줘야 하는 경우가 아니라면 다음과 같이 단순하게 데이터만 추가해주면 자동으로 documentID가 할당된다.
func uploadPost(caption: String, ownerName: String, ownerUid: String) {
let data = ["caption": caption,
"ownerName": ownerName,
"ownerUid": ownerUid
]
Firestore.firestore().collection("post").addDocument(data: data) { error in
if let error = error {
print("DEBUG: \(error.localizedDescription)")
return
}
.
.
.
}
}
모든 데이터 가져오기
Firestore.firestore().collection({컬렉션 이름}).getDocuments(completion:)
func getUsers() {
Firestore.firestore().collection("user").getDocuments { snapshot, error in
if let error = error {
print("DEBUG: \(error.localizedDescription)")
return
}
guard let documents = snapshot?.documents else { return } // document들을 가져옴
let users = documents.compactMap( { try? $0.data(as: User.self) }) // User 구조체로 전부 매핑
.
.
.
}
}
FirebaseStorage 라이브러리
이미지, 영상, 문서등의 파일들을 저장할 수 있도록 해주는 API 함수들을 제공한다. FirebaseStorage에서 제공하는 API를 이용하여 파일을 저장하면 파이어베이스 관리자 페이지에서는 아래와 같이 구조가 이루어진다.
여기서는 사진을 저장하고 저장한 사진의 Url 주소를 가져오는 API함수를 다뤄보도록 한다.
- 파일 저장: Storage.storage().reference(withPath:).putData(_:metadata:completion:)
- 파일 URL: Storage.storage().reference(withPath:).downLoadURL(completion:)
func uploadImage(image: UIImage) {
// jpeg 파일의 퀄리티를 반으로 해서 가져오기, jpege 파일이 아니면 리턴
guard let imageData = image.jpegData(compressionQuality: 0.5) else { return }
// E621E1F8-C36C-495A-93FC-0C247A3E6E5F 형식으로 이미지 이름 짓기
let filename = NSUUID().uuidString
let ref = Storage.storage().reference(withPath: "폴더이름은/알아서지어요/\(filename)")
// 이미지 업로드 하기
ref.putData(imageData, metadata: nil) { data, error in
if let error = error {
print("DEBUG: \(error.localizedDescription)")
return
}
// 업로드한 이미지 url 가져오기
ref.downloadURL { url, _ in
guard let imageUrl = url?.absoluteString else { return }
print("URL: \(imageUrl)")
}
}
}
Leave a comment