0
import Foundation
import Firebase
import FirebaseStorage
import FirebaseStorageSwift
import UIKit

class UploadViewModel : ObservableObject {
    
    @Published var loading : Bool = false
    
    func storeImageWithUrl(images : [UIImage], completion : @escaping (_ urls : [String]) -> ()) {
        
        self.loading = true
        
        var urls : [String] = []
        
        for image in images {
            
            let ref = Storage.storage().reference(withPath: UUID().uuidString)
            
            guard let imageData = image.jpegData(compressionQuality: 0.5) else {return}
            
            ref.putData(imageData, metadata: nil) { metaData, error in
                if let error = error {
                    print("failed to push image cause of error")
                    return
                }
                
                ref.downloadURL { url, error in
                    if let error = error {
                        print("error to make url")
                        return
                    }
                    guard let url = url else {return}
                    urls.append(url.absoluteString)
                    print(urls)
                }
            }
        }
        completion(urls)
    }
    
    func storeItemInformation(title : String, description : String, category : String, contactInfo : String, price : String, imageUrls : [String], timeStamp : Date = Date(), completion : @escaping (_ result : Bool) -> ()) {
        
        let uid = AuthService.instance.makeUid()
        
        guard let userData = ["title": title, "description" : description, "category" : category, "price" : price, "imageURL" : imageUrls, "timestamp" : timeStamp, "contactInfo" : contactInfo] as? [String : Any] else { return }
        
        Firestore.firestore()
            .collection("WholeItems")
            .document(UUID().uuidString)
            .setData(userData) { error in
                if let error = error {
                    print("Error to save whole Data")
                    completion(false)
                    return
                }
                print("Success to save whole data")
        
                Firestore.firestore()
                    .collection("UserItems")
                    .document(uid)
                    .collection(uid)
                    .document(UUID().uuidString)
                    .setData(userData) { error in
                        if let error = error {
                            print("Error to save userData")
                            completion(false)
                            return
                        }
                        
                    self.loading = false
                    print("Success to save user data")
                    completion(true)
                }
        }
    }
}

The code above is about saving data with image. To save multiple images, I made several URLs about image in Storage and made completion using URLs to save data in firestore.

However, except imageURL array, Every data in the dictionary is saved well. I don't know why weren't the imageURLs saved to firestore.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Kyungyun Lee
  • 115
  • 9
  • 1
    Put data is async, completion runs before it is done – lorem ipsum May 11 '22 at 14:11
  • 1
    The call to downloadURL is asynchronous and returns immediately. The callback is invoked some time later, after your function returns an empty list. – Doug Stevenson May 11 '22 at 14:21
  • @lorem ipsum thank you for your lesson!, I'm sorry but how I can handle async func exactly? I don't how I can the call back with Async. could you give me some example code?. thank you! – Kyungyun Lee May 11 '22 at 14:39
  • There are many ways. I would convert the async functions to async await. It is quite simple and it will make coding much easier in the long run. Watch the “Meet async await” video from WWDC 21 – lorem ipsum May 11 '22 at 14:44
  • I wrote an answer that addresses a similar issue with deleting documents. Take a look at [this answer](https://stackoverflow.com/questions/72237054/swift-for-loop-not-waiting-for-firestore-call-to-complete/72241370#72241370) and see if it helps. – Jay May 16 '22 at 18:05

0 Answers0