Swift Firebase 'FIRInvalidArgumentException' 更新数据时
Swift Firebase 'FIRInvalidArgumentException' when updating data
简而言之,我正在使用图像选择器将图像上传到 firebase 存储并将图像 ID 保存到 firestore 中的文档中。图片已成功上传,但在尝试将数据保存到文档时出现错误:'FIRInvalidArgumentException',原因:'Unsupported type: __SwiftValue'
为什么会这样?
调用上传图片,然后保存到文档:
ImagePickerView(currentEventID: self.liveEventID, configuration: self.pickerConfig) { imagesData in
print("PICKER DONE: \(imagesData)")
var eventImages: [EventImage] = []
for imageData in imagesData {
let imageUUID = UUID().uuidString
self.isvm.uploadImage(currentEventID: self.liveEventID, imageUUID: imageUUID, selectedImagesData: imageData) { imageURL in
eventImages.append(EventImage(id: imageUUID, url: imageURL, voteCount: 1))
if eventImages.count == imagesData.count {
print("LOOP DONE: \(eventImages)")
self.isvm.saveImagesToEvent(currentEventID: self.liveEventID, eventImages: eventImages) { isSavedToEvent in
if isSavedToEvent {
print("SAVED IMAGES SUCCESSFULLY")
self.isReloadingImages = true
self.isvm.getUpdatedEventPhotos(currentEventID: self.liveEventID) { liveEvent in
self.liveEvent = liveEvent
if !self.liveEvent.isEmpty {
self.liveEventID = self.liveEvent[0].id
self.isReloadingImages = false
}
}
}
}
}
}
}
}
错误发生的地方:
public func saveImagesToEvent(currentEventID: String, eventImages: [EventImage], completion: @escaping (_ isSavedToEvent: Bool) -> Void) {
self.eventsDataCollection.document(currentEventID).updateData([
"eventImages" : FieldValue.arrayUnion(eventImages)
]) { error in
if let error = error {
print("ERROR SAVING URLS TO EVENT: \(error)")
completion(false)
}
}
completion(true)
}
数据模型:
struct EventModel: Identifiable, Codable {
var id: String
var isLive: Bool
var coors: [Coor]
var eventCenterCoorFormatted: [Double]
var hostTitle: String
var eventName: String
var eventDescription: String
var isEventPrivate: Bool
var eventGuestsJoined: [String]
var eventEndDate: String
var eventImages: [EventImage]
private enum CodingKeys: String, CodingKey {
case id
case isLive
case coors
case eventCenterCoorFormatted
case hostTitle
case eventName
case eventDescription
case isEventPrivate
case eventGuestsJoined
case eventEndDate
case eventImages
}
}
struct Coor: Identifiable, Codable {
var id = UUID()
var coorDoubles: [Double]
private enum CodingKeys: String, CodingKey {
case coorDoubles
}
}
struct EventImage: Identifiable, Codable {
var id = UUID().uuidString
var url: String
var voteCount: Int
private enum eventImage: String, CodingKey {
case id
case imageURL
case voteCount
}
}
请注意:错误前的最后一个打印语句是:"Loop done: "并且它成功获取了所有 EventImage 类型的 eventImages。
该错误是由于试图在您的 saveImagesToEvent
函数中将自定义 Swift 对象保存到 Firestore 引起的:
"eventImages" : FieldValue.arrayUnion(eventImages)
您需要先对 EventImage
对象进行编码,然后再尝试将它们存储在 Firestore 中。您的 EventImage
结构已经符合 Codable
,但 Firestore 的 set/update 数据方法不会自动编码您的数据。
要解决此问题,请确保您已在项目中包含 Firestore swift 扩展:
pod 'FirebaseFirestoreSwift'
现在您可以使用 Firestore.Encoder
在将数据发送到 Firestore 之前对其进行编码:
val encodedEventImages = eventImages.map { Firestore.Encoder().encode([=10=]) }
self.eventsDataCollection.document(currentEventID).updateData([
"eventImages" : FieldValue.arrayUnion(encodedEventImages)
]) { error in
...
如果您想将 Firestore 文档中的数据作为自定义 Swift 对象读取,您需要像本例中那样从 Firestore documentation:
中对其进行解码
docRef.getDocument { (document, error) in
// Construct a Result type to encapsulate deserialization errors or
// successful deserialization. Note that if there is no error thrown
// the value may still be `nil`, indicating a successful deserialization
// of a value that does not exist.
//
// There are thus three cases to handle, which Swift lets us describe
// nicely with built-in Result types:
//
// Result
// /\
// Error Optional<City>
// /\
// Nil City
let result = Result {
try document?.data(as: City.self)
}
switch result {
case .success(let city):
if let city = city {
// A `City` value was successfully initialized from the DocumentSnapshot.
print("City: \(city)")
} else {
// A nil value was successfully initialized from the DocumentSnapshot,
// or the DocumentSnapshot was nil.
print("Document does not exist")
}
case .failure(let error):
// A `City` value could not be initialized from the DocumentSnapshot.
print("Error decoding city: \(error)")
}
}
简而言之,我正在使用图像选择器将图像上传到 firebase 存储并将图像 ID 保存到 firestore 中的文档中。图片已成功上传,但在尝试将数据保存到文档时出现错误:'FIRInvalidArgumentException',原因:'Unsupported type: __SwiftValue'
为什么会这样?
调用上传图片,然后保存到文档:
ImagePickerView(currentEventID: self.liveEventID, configuration: self.pickerConfig) { imagesData in
print("PICKER DONE: \(imagesData)")
var eventImages: [EventImage] = []
for imageData in imagesData {
let imageUUID = UUID().uuidString
self.isvm.uploadImage(currentEventID: self.liveEventID, imageUUID: imageUUID, selectedImagesData: imageData) { imageURL in
eventImages.append(EventImage(id: imageUUID, url: imageURL, voteCount: 1))
if eventImages.count == imagesData.count {
print("LOOP DONE: \(eventImages)")
self.isvm.saveImagesToEvent(currentEventID: self.liveEventID, eventImages: eventImages) { isSavedToEvent in
if isSavedToEvent {
print("SAVED IMAGES SUCCESSFULLY")
self.isReloadingImages = true
self.isvm.getUpdatedEventPhotos(currentEventID: self.liveEventID) { liveEvent in
self.liveEvent = liveEvent
if !self.liveEvent.isEmpty {
self.liveEventID = self.liveEvent[0].id
self.isReloadingImages = false
}
}
}
}
}
}
}
}
错误发生的地方:
public func saveImagesToEvent(currentEventID: String, eventImages: [EventImage], completion: @escaping (_ isSavedToEvent: Bool) -> Void) {
self.eventsDataCollection.document(currentEventID).updateData([
"eventImages" : FieldValue.arrayUnion(eventImages)
]) { error in
if let error = error {
print("ERROR SAVING URLS TO EVENT: \(error)")
completion(false)
}
}
completion(true)
}
数据模型:
struct EventModel: Identifiable, Codable {
var id: String
var isLive: Bool
var coors: [Coor]
var eventCenterCoorFormatted: [Double]
var hostTitle: String
var eventName: String
var eventDescription: String
var isEventPrivate: Bool
var eventGuestsJoined: [String]
var eventEndDate: String
var eventImages: [EventImage]
private enum CodingKeys: String, CodingKey {
case id
case isLive
case coors
case eventCenterCoorFormatted
case hostTitle
case eventName
case eventDescription
case isEventPrivate
case eventGuestsJoined
case eventEndDate
case eventImages
}
}
struct Coor: Identifiable, Codable {
var id = UUID()
var coorDoubles: [Double]
private enum CodingKeys: String, CodingKey {
case coorDoubles
}
}
struct EventImage: Identifiable, Codable {
var id = UUID().uuidString
var url: String
var voteCount: Int
private enum eventImage: String, CodingKey {
case id
case imageURL
case voteCount
}
}
请注意:错误前的最后一个打印语句是:"Loop done: "并且它成功获取了所有 EventImage 类型的 eventImages。
该错误是由于试图在您的 saveImagesToEvent
函数中将自定义 Swift 对象保存到 Firestore 引起的:
"eventImages" : FieldValue.arrayUnion(eventImages)
您需要先对 EventImage
对象进行编码,然后再尝试将它们存储在 Firestore 中。您的 EventImage
结构已经符合 Codable
,但 Firestore 的 set/update 数据方法不会自动编码您的数据。
要解决此问题,请确保您已在项目中包含 Firestore swift 扩展:
pod 'FirebaseFirestoreSwift'
现在您可以使用 Firestore.Encoder
在将数据发送到 Firestore 之前对其进行编码:
val encodedEventImages = eventImages.map { Firestore.Encoder().encode([=10=]) }
self.eventsDataCollection.document(currentEventID).updateData([
"eventImages" : FieldValue.arrayUnion(encodedEventImages)
]) { error in
...
如果您想将 Firestore 文档中的数据作为自定义 Swift 对象读取,您需要像本例中那样从 Firestore documentation:
中对其进行解码docRef.getDocument { (document, error) in
// Construct a Result type to encapsulate deserialization errors or
// successful deserialization. Note that if there is no error thrown
// the value may still be `nil`, indicating a successful deserialization
// of a value that does not exist.
//
// There are thus three cases to handle, which Swift lets us describe
// nicely with built-in Result types:
//
// Result
// /\
// Error Optional<City>
// /\
// Nil City
let result = Result {
try document?.data(as: City.self)
}
switch result {
case .success(let city):
if let city = city {
// A `City` value was successfully initialized from the DocumentSnapshot.
print("City: \(city)")
} else {
// A nil value was successfully initialized from the DocumentSnapshot,
// or the DocumentSnapshot was nil.
print("Document does not exist")
}
case .failure(let error):
// A `City` value could not be initialized from the DocumentSnapshot.
print("Error decoding city: \(error)")
}
}