'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 |