ios – How to upload an image with text to Firebase to specific user swiftui

0
196


I have a Group of textfields, and I already can upload it to my collection items in Firebase, also I have an ImagePicker, I can choose photo but I can’t upload it to my Storage to get URL for userId to use it in the future.

        Group {
            Section(header: Text("New Item")) {
                TextField("Title", text: $viewModel.singleitem.title)
                TextField("Description", text: $viewModel.singleitem.description)
            }
            
            Section(header: Text("Author")) {
                TextField("Author", text: $viewModel.singleitem.author)
            }
            
            if mode == .edit {
                Section {
                    Button("Delete item") { self.presentActionSheet.toggle() }
                        .foregroundColor(.red)
                }
            }
            
        }

Then I tried this part of code to do it from documentation of Firebase…

    private func persistImageToStorage() {
//      let filename = UUID().uuidString
        guard let uid = Auth.auth().currentUser?.uid else { return }
        let ref = Storage.storage().reference(withPath: uid)
        guard let imageData = self.image?.jpegData(compressionQuality: 0.5) else { return }
        ref.putData(imageData, metadata: nil) { metadata, err in
            if let err = err {
                self.loginStatusMessage = "Failed to push image to Storage: \(err)"
                return
            }
            
            ref.downloadURL { url, err in
                if let err = err {
                    self.loginStatusMessage = "Failed to retrieve downloadURL: \(err)"
                    return
                }
                
                self.loginStatusMessage = "Successfully stored image with url: \(url?.absoluteString ?? "")"
                print(url?.absoluteString)
            }
        }
    }
}

…to use this thing to execute persistImageToStorage(), the same like I upload my text to Firebase:

func handleDoneTapped() {
  self.viewModel.handleDoneTapped()
  self.persistImageToStorage()
  self.dismiss()

But it’s also not works..

This is how I call method to add items (currently able only text)

class NewItemView: ObservableObject {
  // MARK: - Public properties
  
  @Published var singleitem: SningleItem
  @Published var modified = false
  
  // MARK: - Internal properties
  
  private var cancellables = Set<AnyCancellable>()
  
  // MARK: - Constructors
  
    init(singleitem: SningleItem = SningleItem(title: "", author: "", description: "", image: "")) {
    self.singleitem = singleitem
    
      self.$singleitem
      .dropFirst()
      .sink { [weak self] singleitem in
        self?.modified = true
      }
      .store(in: &self.cancellables)
  }
  
  // MARK: - Firestore
  
  private var db = Firestore.firestore()
  
  private func addItem(_ singleitem: SningleItem) {
    do {
        var addedItem = singleitem
        addedItem.userId = Auth.auth().currentUser?.uid
        _ = try db.collection("items").addDocument(from: addedItem)
    }
    catch {
      print(error)
    }
  }
    
  
  private func updateItem(_ singleitem: SningleItem) {
    if let documentID = singleitem.id {
      do {
          try db.collection("items").document(documentID).setData(from: singleitem)
      }
        
      catch {
        print(error)
      }
    }
  }
  
  private func updateOrAddItem() {
      if singleitem.id != nil {
      self.updateItem(self.singleitem)
    }
    else {
      addItem(singleitem)
    }
  }
  
  private func removeItem() {
    if let documentID = singleitem.id {
      db.collection("items").document(documentID).delete { error in
        if let error = error {
          print(error.localizedDescription)
        }
      }
    }
  }
  
  // MARK: - UI handlers
  
  func handleDoneTapped() {
    self.updateOrAddItem()
  }
  
  func handleDeleteTapped() {
    self.removeItem()
  }
  
    
    
}

SingleItem

struct SingleItem: Identifiable, Codable {
  @DocumentID var id: String?
    var title : String
    var author : String
    var description : String
    @ServerTimestamp var createdTime: Timestamp?
    var userId : String?
    var image : String
}
  
  enum CodingKeys: String, CodingKey {
    case id
    case title
    case author
    case description = ""
    case image
  }

Сan someone explain what the problem is? Thanks.