Firebase에서 제공하는 기능들을 제대로 알고자 정리를 해보았습니다.
현재 프로젝트하면서 쓰이는 메서드를 위주로 정리했습니다. 😁
참고: https://firebase.google.com/docs/database/ios/read-and-write?hl=ko
Firebase 데이터 관련 🥝
FIRDatabaseReference 가져오기
- 데이터베이스에서 데이터를 읽거나 쓰기 위해선 FIRDatabaseReference 인스턴스가 필요합니다.
DB_REF = Database.database().reference()
DB_REF = FIRDatabase.database().reference()
child ▾
- 파일 업로드 관련해서 파일에 대한 참조를 생성합니다.
// 업로드 하려는 파일에 대한 참조 생성
let REF_USERS = DB.REF.child("users")
childByAutoId ▾
언제 쓰는걸까 ?
- 멀티 사용자 애플리케이션에서 목록에 데이터를 추가할 때 위 메서드를 사용하게 됩니다.
Information ▾
- 지정된 Firebase 참조에 새 하위 항목이 추가될 때마다 고유 키를 생성합니다.
- 목록의 새 요소마다 이러한 자동 생성키를 사용하면 여러 클라이언트에서 쓰기 충돌 없이 동시에 같은 위치에 하위 요소를 추가할 수 있습니다.
- 위 메서드를 통해 생성하는 고유 키는 타임스탬프에 기반하므로 목록 항목은 시간순으로 자동 정렬됩니다.
updateChildValues ▾
- 하위 이벤트는 노드의 하위 요소에서 발생하는 특정 작업에 대응하여 트리거 되는데, 하위 요소가 childByAutoId 메서드를 통해 새로 추가되거나 updateChildValues 메서드를 통해 업데이트됩니다.
observe ▾
- 문서에서는 "경로의 전체 내용을 읽고 변경사항을 수신 대기합니다." 라고 합니다.
- 이벤트 발생 시점에 존재하는 지정된 경로에서 데이터를 읽을 수 있는데, 리스너가 연결될 때 한 번 트리거 된 후 하위 요소를 포함하여 데이터가 변경될 때마다 다시 트리거 됩니다.
- *트리거: (DB)테이블에 대한 이벤트에 반응해 자동으로 실행되는 작업을 의미
- 하위 데이터를 포함하여 해당 위치의 모든 데이터를 포함하는 snapshot이 이벤트 콜벡에 전달됩니다.
- 데이터가 없다면 snapshot은 exists()를 호출할 때 false를 반환하고 value 속성을 읽을 때 nil을 반환합니다.
REF_USER_FOLLOWING.child(uid).observe(.childAdded) { snapshot in
print("DEBUG: snapshot key is \(snapshot.key)")
}
observeSingleEvent ▾
- 경우에 따라 서버의 업데이트된 값을 확인하는 대신 로컬 캐시의 값을 즉시 반환하고 싶을 때 사용한다.
- 이를 이용해 로컬 디스크 캐시에서 데이터를 즉시 가져올 수 있습니다.
- 한 번 로드된 후 자주 변경되지 않거나 능동적으로 수신 대기할 필요가 없는 데이터에 유용합니다.
REF_TWEETS.child(tweetID).observeSingleEvent(of: .value) { snapshot in
guard let dictionary = snapshot.value as? [String:Any] else { return }
print("DEBUG: dictionary is \(dictionary)")
}
updateChildValues ▾
- 다른 하위 노드를 덮어쓰지 않고 특정 하위 노드에 동시에 쓰려고 할 때 이 메서드를 사용합니다.
- updateChildValues를 호출할 때 키 경로를 지정하여 더 낮은 수준의 하위 항목 값을 업데이트할 수 있습니다.
- 확장선 개선을 위해 데이터를 여러 위치에 저장한 경우 데이터 팬아웃을 사용하여 해당 데이터의 모든 인스턴스를 업데이트할 수 있습니다.
- 예를 들어 소셜 블로깅 앱에서 게시물을 생성한 후 최근 활동 피드 및 게시자의 활동 피드에 동시에 업데이트해야 할 수 있습니다.
guard let key = REF.child("posts").childByAutoId().key else { return }
let post = [ "uid": userID,
"author": username,
"title": title,
"body": body }
let childUpdates = [ "\posts/\(key)": post,
"/user-posts/\(userID)/\(key)/": post ]
REF.updateChildValues(childUpdates)
- 이해를 위해 더 보자면 childByAutoId 를 사용하여 모든 사용자의 게시물을 포함하는 노드 (/posts$postid)에서 게시물을 작성하는 동시에 getKey() 로 키를 검색합니다.
- 그다음 위 키를 사용하여 /user-posts/$userid/$postid 에서 사용자의 게시물에 두 번째 항목을 작성합니다.
- 이 경로를 사용하면 이 예시에서 두 위치에 새 게시물을 생성하는 것처럼 updateChildValues 를 한 번만 호출하여 JSON 트리의 여러 위치에서 동시에 업데이트를 수행할 수 있습니다.
removeValue ▾
- 데이터를 삭제하는 가장 간단한 방법은 해당 데이터 위치의 참조에 removeValue 를 호출하는 것입니다.
- setValue 또는 updateChildValues 등의 다른 쓰기 작업 값으로 nil 을 지정하여 삭제할 수도 있습니다.
- updateChildValues 에 이 방법을 사용하면 API 호출 한 번으로 여러 하위 항목을 삭제할 수 있습니다.
func likeTweet(tweet: Tweet, completion: @escaping(DatabaseCompletion)) {
guard let uid = Auth.auth().currentUser?.uid else { return }
let likes = tweet.didLike ? tweet.likes - 1 : tweet.likes + 1
REF_TWEETS.child(tweet.tweetID).child("likes").setValue(likes)
if tweet.didLike {
REF_USER_LIKES.child(uid).child(tweet.tweetID).removeValue { (err, ref) in
REF_TWEET_LIKES.child(tweet.tweetID).removeValue(completionBlock: completion)
}
}
}
- 게시물을 좋아요 누른 상태라면 다시 좋아요 누를 시 취소가 되어야 하므로, 좋아요 데이터 삭제를 위한 removeValue 사용
더 많은 기능들을 알 수 있었지만 현재 프로젝트에서 쓰이는 기능들만 정리를 해보았습니다.
'아 이런 기능이 있고, 이런 식으로 사용할 수 있겠구나' 정도로만 가볍게 봐주세요 😁
'Udemy.zip' 카테고리의 다른 글
[Swift]RxSwift 기초 문법 (0) | 2022.04.13 |
---|---|
[Swift]Table View 이슈 (0) | 2022.03.05 |
[Swift]Model 동기화 (0) | 2022.02.27 |
[Swift]ActionSheet-Protocol (0) | 2022.02.25 |