'SwiftUI: upload multiple images to Firebase
Goal: upload 3 images from SwiftUI app to Firebase, with different URL for each.
Problem: I only managed to upload 1.
What I have tried (but didn't work).... :
storagePostRef.putData(image1, image2, image3, metadata: metadata) { (storageMetadata, error) in
Full function bellow:
static func savePostPhoto(
//id
userId: String,
image1: Data,
image2: Data,
image3: Data,
// imagesArray : [Data],
metadata: StorageMetadata,
storagePostRef: StorageReference,
onSuccess: @escaping() -> Void,
onError: @escaping(_ errorMessage: String) -> Void)
{
let arrayOfImages : [Data] = [image1, image2, image3]
//image storage
storagePostRef.putData(image1, metadata: metadata) { (storageMetadata, error) in
if error != nil {
onError(error!.localizedDescription)
return
}
//image URL
storagePostRef.downloadURL { (url, error) in
let image1 = url?.absoluteString
let image2 = url?.absoluteString
let image3 = url?.absoluteString
}
}
}
Solution 1:[1]
Each call to putData stores a single image, in the location that you call putData on.
So if you want to store three separate images, you'll have to call putData on three difference StorageReference objects. To then get the three download URLs, you call downloadURL on each of the three StorageReference objects too.
storagePostRef1.putData(image1, metadata: metadata) { (storageMetadata, error) in
storagePostRef1.downloadURL { (url1, error) in
let image1 = url?.absoluteString storagePostRef2.putData(image2, metadata: metadata) { (storageMetadata, error) in
storagePostRef2.downloadURL { (url2, error) in
storagePostRef3.putData(image3, metadata: metadata) { (storageMetadata, error) in
storagePostRef3.downloadURL { (url3, error) in
You can probably clean this up a bit, by creating your own helper function that handles the calls to putData and downloadUrl with a single closure/callback.
Solution 2:[2]
This works pretty well.
var photoArrayModel = PhotoArrayModel(photoArray: [])
let userPhotosFirstoreRef = self.ref.document(uid)
imagesData.enumerated().forEach { index, imageData in
let userPhotosStorageRef = self.storageRoot.child("user_photos").child(uid).child("image_\(index)")
userPhotosStorageRef.putData(imageData, metadata: nil) { metaData, error in
if error != nil {
promise(.failure(.uploadingPhoto))
}
userPhotosStorageRef.downloadURL { url, error in
if error != nil {
promise(.failure(.uploadingPhoto))
}
guard let urlString = url?.absoluteString else { return promise(.failure(.uploadingPhoto))}
let photo = PhotoModel(ownerID: uid, imageURL: urlString, timeStamp: Date().millisecondsSince1970)
photoArrayModel.photoArray.append(photo)
if photoArrayModel.photoArray.count == imagesData.count {
do {
try userPhotosFirstoreRef.setData(from: photoArrayModel.self)
promise(.success(()))
} catch {
promise(.failure(.uploadingPhoto))
}
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Frank van Puffelen |
| Solution 2 | vebbis |
