swiftui 에서 firebase를 활용해 다음과 같이 사용자별로 이메일, 객체 배열을 저장했다.
이후, 구글을 통해 객체 배열을 삭제하는 함수를 작성했는데, 화면에서는 함수가 제대로 작동하는 것처럼 나왔지만, 실제 firebase에서는 데이터가 일부만 삭제되는 현상이 발생했다.
이러한 현상은 Date 타입을 사용하는 경우 발생한다고 한다. 현재 Package model 코드는 다음과 같다.
struct Packages: Codable, Hashable {
var timeStamp: Date
var trackCompany: String
var trackNumber: String
var setTrackNumber: [String: Any] {
return [
"timeStamp": self.timeStamp,
"trackCompany": self.trackCompany,
"trackNumber": self.trackNumber
]
}
enum CodingKeys: String, CodingKey {
case timeStamp
case trackCompany = "trackCompany"
case trackNumber = "trackNumber"
}
}
timeStamp의 타입은 Date인데 Firestore가 데이터베이스에 저장될 때 Firestore 고유의 날짜 개체로 변환되는(?) 문제가 발생해 이러한 현상이 나타난다고 한다.
해당 내용에 대한 자세한 설명이 필요하다면 다음 링크를 참조하면 될 것 같다.
Removing an array item from Firestore not working when array contains date
I've spent days researching this including various answers like: Firebase Firestore: Append/Remove items from document array and my previous question at: Removing an array item from Firestore but c...
stackoverflow.com
완성 코드는 다음과 같다.
func deleteTrackNumber(trackNumber: String, trackCompany: String) {
let db = Firestore.firestore()
guard let value = trackInfo?.userTracksInfo else {
return
}
guard let deleteItem = value.first(where: { $0.trackCompany == trackCompany && $0.trackNumber == trackNumber }) else {
print("CANNOT FIND ITEM TO DELETE")
return
}
db.runTransaction{ (trans, errorPointer) -> Any? in
let doc: DocumentSnapshot
let docRef = db.collection("users").document(self.currentUser!.uid)
// get the document
do {
try doc = trans.getDocument(docRef)
} catch let error as NSError {
errorPointer?.pointee = error
return nil
}
// get the items from the document
if let items = doc.get("userTracksInfo") as? [[String: Any]] {
// find the element to delete
if let toDelete = items.first(where: { (element) -> Bool in
// the predicate for finding the element
if let number = element["trackNumber"] as? String,
number == trackNumber {
return true
} else {
return false
}
}) {
// element found, remove it
docRef.updateData([
"userTracksInfo": FieldValue.arrayRemove([toDelete])
])
}
} else {
// array itself not found
print("items not found")
}
return nil // you can return things out of transactions but not needed here so return nil
} completion: { (_, error) in
if let error = error {
print(error)
} else {
print("transaction done")
}
}
}
*추가
(해당 코드에서
Type of expression is ambiguous without more context
Cannot find type 'DocumentSnapshot' in scope
와 같은 에러가 발생했는데 정상적으로 빌드가 되는 것을 보면 xcode상의 문제인건가 싶기도 하다)
'iOS 개발 > SwiftUI' 카테고리의 다른 글
[SwiftUI] - firebase 회원가입, 로그인 시 에러 처리 View에 적용하기 (0) | 2023.01.31 |
---|---|
[SwiftUI] firebase firstore 데이터 CRUD (0) | 2023.01.31 |
[SwiftUI] - Firebase Firestore 데이터 저장하기, Cannot convert value of type 'TrackInfo' to expected argument type '[String : Any] 오류 해결 (1) | 2023.01.23 |
[SwiftUI] - custom list item 만들기 (0) | 2023.01.17 |
[SwiftUI] - 설정 화면(View) 구현하기 (2) | 2023.01.07 |