오늘은 앱 내 다양한 라이브러리를 바탕으로 생체데이터, 생활 데이터 등 이용자의 데이터를 수집하고 해당 데이터를 저장하기 위해 firebase에 데이터를 저장하는 방식에 대해서 알아보려고 한다.
이전에 다룬적이 있으니 SPM을 통해 firebase 를 추가하고 firebase에서 콘솔에 프로젝트를 추가해 GoogleService-Info.plist를 추가하는 과정은 생략하고 진행해보자 ㅎㅎ 이미 많이 해봤으니까!
firebase 중 realtimeDatabase에 데이터를 저장하는 과정을 기록해보려고 한다.
먼저 Firebase 데이터 베이스에 접근하기 위해 Database 참조를 생성해 담아주어야 한다.
private let realtimeDatabase = Database.database().reference()
이런 방식을 통해 루트 참조를 생성하고 클래스의 초기화 과정에서 이를 생성해 어디서든 사용할 수 있도록 구현할 수도 있다.
그런 다음 저장할 데이터의 구조를 먼저 정의해야 데이터를 넣을 수 있기 때문에 데이터 모델을 먼저 생성한다. 해당 예시는 이용자의 음성을 기록할 수 있는 로직을 기준으로 작성했다.
struct TelephonySpeechMetricsDataPoint: Identifiable, Encodable {
var id = UUID()
let timestamp: Int64
let confidence: Double
let mood: Double
let valence: Double
let activation: Double
let dominance: Double
let audioLevel: Double?
let speechRecognitionResult: String?
}
그 다음 데이터를 Firebase Realtime Database에 저장할 때 특정 경로로 저장할 수 있게 참조를 만들고 데이터를 설정해줄 수 있다.
경로를 한번 지정해보자 특정 경로로 데이터를 저장하기 위해서 realtimeDatabase.child() 메서드를 활용해 경로를 원하는 곳에 설정해 저장할 수 있다. pinNumber와 deviceModel을 구분을 해줘야 하는 상황이기 때문에 트리 구조로 iOS → pinNumber → deviceModel → SpeechMetricsData 이런 방식으로 데이터를 구분해 넣어줄 예정이다.
이 과정을 코드로 작성하면
let speechDataRef = realtimeDatabase.child("iOS").child(pinNumber).child(deviceModel).child("TelephonySpeechMetricsData")
이렇게 child를 넣어 간단하게 설정할 수 있다. firebase가 많이 쓰이는 이유를 좀 알겠다.. 뭔가 처음 사용을해도 굉장히 쉽고 간편하게 사용할 수 있다는 점이 아주 장점인 것 같다.
그리고 데이터를 저장할 때 아무래도 중복된 데이터는 저장되지 않는게 좋기 때문에 firebase 내 저장된 데이터와 이제 저장할 데이터가 중복인지 여부를 판단해 새로운 데이터만 들어갈 수 있도록 구현할 예정이다.
이렇게 구현하기 위해서 사용한 방식은 queryOrdered(byChild:)이다 이 메서드를 활용하면 지정한 childKey의 값을 기준으로 해당 데이터의 자식 노드들을 정렬해 검색할 수 있도록 한다.
즉, 특정 키를 기준으로 데이터 검색 후 데이터 중복 확인해 필터링 된 결과에서 최소값 또는 최대값을 기준으로 데이터를 제한한다.
speechDataRef.queryOrdered(byChild: "timestamp").queryEqual(toValue: speechData.timestamp).observeSingleEvent(of: .value) { snapshot in
if snapshot.exists() {
print("중복된 데이터가 이미 저장되어 있습니다.")
} else {
// 고유 ID 생성 후 데이터 삽입
let newSpeechDataRef = speechDataRef.childByAutoId()
// 저장할 데이터를 딕셔너리 형태로 준비
let dataToUpload: [String: Any] = [
"timestamp": speechData.timestamp,
"confidence": speechData.confidence,
"mood": speechData.mood,
"valence": speechData.valence,
"activation": speechData.activation,
"dominance": speechData.dominance,
"audioLevel": speechData.audioLevel ?? "
]
// 데이터베이스에 데이터 삽입
newSpeechDataRef.setValue(dataToUpload) { error, _ in
if let error = error {
print("데이터 업로드 실패: \\(error.localizedDescription)")
} else {
print("데이터 업로드 성공")
}
}
}
}
상기 내용을 바탕으로 데이터를 저장할때 queryOrdered(byChild:) 를 활용해 timestamp 값을 정렬해 동일한 timestamp의 값은 데이터 저장을 하지 않고 새로운 값만 들어오도록 구현하였다.
데이터를 저장할 때 Key:Value 타입으로 지정한 뒤 저장하고 싶은 명칭과 저장할 데이터를 지정해주면 아주 쉽게 firebase 저장 구현이 완료된다.
dataToUpload 배열에 데이터가 들어가고 해당 데이터는 setValue를 통해 데이터가 저장되게 된다.
그럼 firebase realtimeDatabase에 데이터가 이렇게 잘 저장되게 된다!!
오늘은 여기까지!!!!
'◽️ Programming > T I L' 카테고리의 다른 글
Custom Calendar 구현과 ViewBuilder에 대해서 (2) | 2024.11.13 |
---|---|
Device 잠금 상태 추적해 백그라운드 데이터 업로드 하기 (0) | 2024.11.07 |
Equatable를 사용하면서 Extension 해야하는 상황 (0) | 2024.09.25 |
[Project 일지] Running App (1) (0) | 2024.08.30 |
Swift의 async/await에 대해서 알아보자 (0) | 2024.08.19 |