Archive/잡동사니

Firebase에 대해서 정리

lgvv 2021. 3. 8. 00:22

서버,,, 내가 제일 못하는 부분이 이 부분이 아닐까 싶다.

근 반년넘게 공부해도 잘 이해가 안가서 사용이 불가능했었는데, 한번쯤은 확실히 하고 넘어가야지.

 

우선 m1 mac을 사용해서 cocoapod 문제도 있었는데, 어떻게 해결했는지, 지금은 잘 된다.

 

firebase 공식 문서를 하나하나 따라하면 쉽게 이해 가능!!

 

db 부분은 실시간 데이터베이스 부분을 사용한다.

(콘솔 창에 보면 storage 부분이 있는데, 이 부분은 사진이나 영상 등 미디어 소스를 여기다가 저장한다고 한다.)

 

우선 cocoapod 설치를 해야하는데 루비 기반으로 만들어져서 외부 라이브러리의 사용을 쉽게 해주어서 mac 개발자라면 대부분이 알고 있다고 한다.

 

코코아팟 설치가 무사히 끝나고 pod init 후 workspace가 만들어지는데 pod 같은것도 통합적으로 관리하는거라나?

 

** 공식문서 - 시작하기 : firebase.google.com/docs/database/ios/start?authuser=0

 

viewController 부분에 추가한다.

var ref: DatabaseReference!
ref = Database.database().reference()

 

** 공식문서 - 데이터 구조화 : firebase.google.com/docs/database/ios/structure-data?authuser=0

 

JSON 트리를 사용한다는데, 내 깃허브에 주석으로 JSON에 대해서 간략정리한게 있는데

딕셔너리 형태, 배열 등 트리 구조로 관리가 가능하다.

 

구조화 부분에서는 우선 JSON 사용한다는 것만 알고 넘어가자.

 

 ** 공식문서 - 데이터 읽기 및 쓰기 : firebase.google.com/docs/database/ios/read-and-write?authuser=0

 

데이터를 읽거나 쓰려면 시작하기 부분에 적어두었던 코드가 필요한데, FIRDatebaseReference의 인스턴스를 사용해야하기 때문이다.

 

(데이터 쓰기)

 참조에 비동기 리스너를 연결해 검색 가능하고, 리스너는 트리거가된 후 데이터가 변경될 때마다 다시 트리거된다.

 

사용가능한 JSON 유형으로는 NSString, NSNumber, NSDictionary, NSArray 가 있다.

( 여기서 prefix로 NS가 붙는 이유는 정확하게는 기억나지 않지만 원래는 애플에서 만든 타입이었다나..? 여튼 string의 애플 형태였던가...  String 객체가 NSString 상속 받아서 만들어진 개념이었나..? 여튼 당시에도 그렇게 중요한게 아니라 살짝 읽고 넘어갔던 기억이 있는데, 우선 패스 ) 

 

self.ref.child("users").child(user.uid).setValue(["username": username]) - 이런 형태로 사용한다고 한다.

 - 코드 리뷰 포스트를 올릴건데 거기서 조금 더 자세히 보도록 하자

 

(데이터 읽기)

 

모든 데이터는 snapshot이 이벤트 콜백에 전달된다. 데이터가 없으면 snapshot은 exitsts()를 호출할 때 false를 반환하고 value 속성을 읽을 때 nil을 반환한다.

 

중요: 하위 요소에 대한 변경을 포함하여 지정된 데이터베이스 참조에서 데이터가 변경될 때마다 FIRDataEventTypeValue 이벤트가 발생합니다. 스냅샷 크기를 제한하려면 변경을 확인해야 하는 최상위 수준에서만 연결하세요. 예를 들어 데이터베이스 루트에는 리스너를 연결하지 않는 것이 좋습니다.

 

// 데베에서 글의 세부정보를 검색하는 소셜 블로깅 애플리케이션의 예

refHandle = postRef.observe(DataEventType.value, with: { (snapshot) in
  let postDict
= snapshot.value as? [String : AnyObject] ?? [:]
 
// ...
})

 

(데이터 한 번 읽기)

 

getData()를 사용하여 한번 읽기 

 

SDK는 앱이 온라인이든 오프라인이든 상관없이 데베 서버와의 상호작용을 관리하도록 설계되었다!!

 

self.ref.child("users/\(user.uid)/username").getData { (error, snapshot) in
   
if let error = error {
       
print("Error getting data \(error)")
   
}
   
else if snapshot.exists() {
       
print("Got data \(snapshot.value!)")
   
}
   
else {
       
print("No data available")
   
}
}

 

(관찰자를 이용하여 데이터를 한번 읽기)

 

업데이트된 값을 확인하는 것이 아닌 로컬 캐시의 값을 즉시 반환하고 싶을 경우 사용한다.

 

let userID = Auth.auth().currentUser?.uid
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
 
// Get user value
  let value
= snapshot.value as? NSDictionary
  let username
= value?["username"] as? String ?? ""
  let user
= User(username: username)

 
// ...
 
}) { (error) in
   
print(error.localizedDescription)
}

 

(데이터 업데이트 및 삭제)

다른 하위 노드를 덮어 쓰지 않고 특정 하위 노드에 동시에 쓰려면 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)

 

(데이터가 커밋된 시점을 파악하기 위한 코드)

 

ref.child("users").child(user.uid).setValue(["username": username]) {
 
(error:Error?, ref:DatabaseReference) in
 
if let error = error {
   
print("Data could not be saved: \(error).")
 
} else {
   
print("Data saved successfully!")
 
}
}

 

(데이터 삭제)

removeValue 통해서 삭제하거나 setValue의 값을 nil로 지정하여 사용 가능

 

 

우선 여기까지..

1인 개발에서는 이정도면 충분하다고 생각하는데,

서비스가 더 커지면 그때 더 공부하지 않을까?

아니면 사람을 쓰던가 ㅇ-ㅇ

 

데이터 다루는 부분이 진짜 너무나도 어렵다.

nodejs 사용하여 만들때도 너무나도 힘들었는데, firebase도 마찬가지다 ㅠ__ㅠ