我有以下代码,我正在尝试将数据保存到Firebase。保存是非常随机的。有时只有第一个.setValue被发布到firebase。有时前两个,有时前三个。它似乎从来没有超过三个。这仅在我添加.putData方法保存图像时才开始发生。如果我注释掉“保存照片”部分,则效果很好。有任何想法吗?顺便说一句,我只是添加了调度队列,看它是否可以解决问题。没有。
private func saveEvents() {
// Createe a database reference
databaseRef = Database.database().reference()
for event in events {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let self = self else {
return
}
let fireKey = event.eventName.trimmingCharacters(in: .whitespaces) + " " + event.eventCity.trimmingCharacters(in: .whitespaces)
self.databaseRef?.child("Event").child(fireKey)
self.databaseRef?.child("Event").child(fireKey).child("eventCategory").setValue(event.eventCategory)
self.databaseRef?.child("Event").child(fireKey).child("eventCity").setValue(event.eventCity)
self.databaseRef?.child("Event").child(fireKey).child("eventContact").setValue(event.eventContact)
self.databaseRef?.child("Event").child(fireKey).child("eventCreator").setValue(event.eventCreator)
self.databaseRef?.child("Event").child(fireKey).child("frequency").setValue(event.frequency)
self.databaseRef?.child("Event").child(fireKey).child("eventDate").setValue(event.eventDate)
self.databaseRef?.child("Event").child(fireKey).child("eventToDate").setValue(event.eventToDate)
self.databaseRef?.child("Event").child(fireKey).child("eventEmail").setValue(event.eventEmail)
self.databaseRef?.child("Event").child(fireKey).child("eventWebSite").setValue(event.eventWebSite)
self.databaseRef?.child("Event").child(fireKey).child("eventName").setValue(event.eventName)
self.databaseRef?.child("Event").child(fireKey).child("eventPhone").setValue(event.eventPhone)
self.databaseRef?.child("Event").child(fireKey).child("eventState").setValue(event.eventState)
self.databaseRef?.child("Event").child(fireKey).child("eventCountry").setValue(event.eventCountry)
self.databaseRef?.child("Event").child(fireKey).child("eventStreet").setValue(event.eventStreet)
for review in event.eventReviews {
let commentKey = event.eventName + " " + review.vendorName
self.databaseRef?.child("Event").child(fireKey).child("Reviews")
self.databaseRef?.child("Event").child(fireKey).child("Reviews").child(commentKey)
self.databaseRef?.child("Event").child(fireKey).child("Reviews").child(commentKey).child("Comment").setValue(review.vendorComment)
self.databaseRef?.child("Event").child(fireKey).child("Reviews").child(commentKey).child("Rating").setValue(review.vendorRating)
self.databaseRef?.child("Event").child(fireKey).child("Reviews").child(commentKey).child("Reviewer").setValue(review.vendorName)
}
//check if there is only a Default image before storing in firebase
if event.eventImage != UIImage(named: "UploadPhoto") {
DispatchQueue.main.async { [weak self] in
let imageRef = self!.databaseRef.child("Event").child(fireKey).child("images").childByAutoId()
let imageStorageKey = imageRef.key
if let imageData = UIImageJPEGRepresentation(event.eventImage, 0.6) {
let imageStorageRef = self!.storageRef.child("images").child(imageStorageKey!)
let uploadTask = imageStorageRef.putData(imageData, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
// Uh-oh, an error occurred!
return
}
// Metadata contains file metadata such as size, content-type
let size = metadata.size
// You can also access to download URL after upload.
imageStorageRef.downloadURL(completion: { (url, error) in
guard let downloadURL = url else {
// Uh-oh, an error occurred!
return
}
self!.imageDownloadURL = downloadURL.absoluteString
imageRef.child("imageDownloadURL").setValue(self!.imageDownloadURL)
})
}
}
}
}
}
}
saveGeoFire()
}
答案 0 :(得分:0)
您可以在数据库中创建子级的数据库引用变量,因此您不必一直输入.child
。
我建议尝试像这样使用Swift Dictionary
一次保存所有值:
// in your loop where you start writing to Firebase
if let databaseRef = databaseRef?.child("Event").child(fireKey) {
let objectToSave = [
"eventCategory": event.eventCatagory,
"eventCity": event.eventCity,
"eventContact": event.eventContact,
// and so on...
"eventStreet": event.eventStreet
] as [String:Any]
databaseRef.setValue(objectToSave) { error, ref in
if error != nil {
// error handle
} else {
// then upload your photo since the write was successful
}
}
}
第二,由于您正在循环中运行异步代码(写入Firebase),因此您将需要适当地处理此问题,因为代码将在数据库调用之前执行。
我建议您考虑使用DispatchQueue。以下是一些StackOverflow相关文章,可以教您如何将其实现到异步函数中:
Wait until swift for loop with asynchronous network requests finishes executing