How to get downloadURL of an existing image from firebase storage - swift

I pushed an image to firebase storage and by using Resize Images Extension, I am able to get a resized image of the same image name plus _240x320. To be clear with you I get the downloadURL of the original image, but I am not understand why I cannot get the downloadURL of the resized image. Here is my code:
func storeImageInFirebase(){
let storeageRef = Storage.storage().reference()
let imageName = UUID().uuidString //+ ".jpg"
let imagesReference = storeageRef.child("images").child(imageName + ".jpg")
let imageData = self.imgView.image!.pngData()
let metaData = StorageMetadata()
var imageName2 = imageName //+ "_240x320.jpg"
let imagesReference2 = storeageRef.child("images").child(imageName2 + "_240x320.jpg")
metaData.contentType = "image/jpg"
imagesReference.putData(imageData!, metadata: metaData){ (metadate, error)
in
guard metadate != nil else{
print("Error: \(String(describing: error?.localizedDescription))")
return
}
// Fetch the download URL
imagesReference.downloadURL(completion: {(url, error)
in
if error != nil {
print("Faild to download url:", error!)
return
}else{
// show the url in real database
print("resized image url ..... \(url?.absoluteString)")
var theUsedURL = self.imgURL = (url?.absoluteString)!
self.sendDataToFirebase()
}
})
// Fetch the download URL
imagesReference2.downloadURL(completion: {(url, error)
in
if error != nil {
print("Faild to download url:", error!)
return
}else{
// show the url in real database
print("resized image url ..... \(url?.absoluteString)")
self.imgURL2 = (url?.absoluteString)!
self.sendDataToFirebase()
}
})
}
}
I wrote two image references, one for the original image and the other one for resized image. I am able to get the original image, but I have error faild to download url and the image does not exist for the resized image, where I can see in the Firebase Storage that the image there. I am trying to solve this from a weeks I will appreciate any help.

Related

download image from firebase storage in swift

Have the image location as gs://olio-ae400.appspot.com/Listings/Food/-M3g8pZDGmApicUAQtOi/MainImage
I want to download from this firebase storage location to imageview.
Have used below code,but the unable to download image from url?
let storage = Storage.storage()
var reference: StorageReference!
reference = storage.reference(forURL: "gs://olio-ae400.appspot.com/Listings/Food/-M3g8pZDGmApicUAQtOi/MainImage")
reference.downloadURL { (url, error) in
print("image url is",url!)
let data = NSData(contentsOf: url!)
let image = UIImage(data: data! as Data)
self.img.image = image
}
Getting error at downloadURL line while retrieving the url for it in the response.
What is the correct way for it to download the image?
Install the pod firebaseUI.
import FirebaseUI
fetch the reference from the storage and set the reference to the imageview directly using SDwebimage as shown below.
let ref2 = Storage.storage().reference(forURL: "gs://hungry-aaf15.appspot.com/Listings/Food/-MV04bNvewyGPHMYUkK9/MainImage")
cell.img.sd_setImage(with: ref2)
Specify path and it's extension, then Use:
let path = "Listings/Food/-M3g8pZDGmApicUAQtOi/MainImage.jpg"
let reference = Storage.storage().reference(withPath: path)
reference.getData(maxSize: (1 * 1024 * 1024)) { (data, error) in
if let err = error {
print(err)
} else {
if let image = data {
let myImage: UIImage! = UIImage(data: image)
// Use Image
}
}
}
For Swift 5.6 and Xcode 13.4
I opened name "Images" folder in Firebase and uploaded my image which name "Corleone" in jpg format.
Firstly I fetch image data then assigned to imageView. Lastly, i downloaded image URL. You can use two method differently.
You can copy all what i wrote and past your project inside of viewDidload or buttonAction.
let storage = Storage.storage().reference().child("Images/Corleone.jpg")
storage.getData(maxSize: 1 * 1024 * 1024) { data, error in
if error != nil {
print(error?.localizedDescription ?? "errror")
}else{
let image = UIImage(data: data!)
self.imageView.image = image
storage.downloadURL { url, error in
if error != nil {
print(error?.localizedDescription ?? "error")
}else {
print(url ?? "url") //https://firebasestorage.googleapis.com/v0/b/epeycompare.appspot.com/o/Images%2FCorleone.jpg?alt=media&token=04c6369d-8036-4aef-8052-bac21c89eeda
}
}
}
}

Using Firebase Storage for Uploading Images

I can only upload a single photo to FirebaseStorage.
All the tutorials I have seen on youtube use FirebaseStorage to save user's profile pictures. However, I am trying to make a restaurant app where I should be able to keep several pictures and not only one. My code right now only allows me to keep one. As soon as I try to upload a second image, it erases the first one.
Here's my code:
#IBAction func agregarComidaFav(_ sender: Any) {
guard let imageData = imagen?.jpegData(compressionQuality: 0.4) else {
return
}
let storageRef = Storage.storage().reference(forURL: "gs://comidas-68043.appspot.com")
let storageProfileRef = storageRef.child("ComidasFavoritas")
let metadata = StorageMetadata()
metadata.contentType = "image/png"
storageRef.child("comidasFavoritas/png").putData(imageData, metadata: metadata) { (storageMetaData, error) in
if error != nil {
print(error?.localizedDescription ?? "")
return
}
}
storageProfileRef.downloadURL(completion: { (url, error) in
if let metaImageUrl = url?.absoluteString {
print(metaImageUrl)
self.imagenURL = metaImageUrl
}
})
var ref: DocumentReference? = nil
ref = db.collection("comidasFavoritas").addDocument(data: [
"imagenURL" : imagenURL
]) { err in
if let err = err {
print("Error agregando comida: \(err)")
} else {
let id = ref!.documentID
print("Comida agregado con ID: \(id)")
}
}
}
This line:
storageRef.child("comidasFavoritas/png").putData(...)
...guarantees that each time, the data is going to be written to "comidasFavoritas/png"
I don't know anything about how you're keeping track of your data/images in your app, but you'll probably need some way to keep track of an ID for that image. Then, when you store it, you could store it like:
storageRef.child("comidasFavoritas/png\(imageId)").putData(...)
You'd probably also want to store that ID in your database when you store the image URL.

imageView doesn't change image when I uploaded new image from firebase storage

I try to get an image from url, First time loaded correct image form url,
But when I uploaded a new image, imageView doesn't change.
And I got this error from console :
[BoringSSL] nw_protocol_boringssl_get_output_frames(1301)
[C7.1:2][0x7fa944135a30] get output frames failed, state 8196
Then I uploaded a new image again,
imageView display last downloaded image and it shows the same error again.
Where is the problem?
ref.child("/user").child(userID).child("UserImage").observe(DataEventType.value, with: {(data) in
let value = data.value as? String ?? ""
print("url:",value)
if let url = URL(string: value) {
URLSession.shared.dataTask(with: url, completionHandler: {(data,responds,error) in
if error != nil{
print(error!.localizedDescription)
}
else if let imageData = data{
DispatchQueue.main.async {
self.userImage.image = UIImage(data: imageData)
}
}
}).resume()
}
})
try adding the SDWEBImage pod
pod "SDWebImage"
then you could just pass in the url
self.userImage.sd_setImage(with: url, completed: nil)
more info about the pod is here https://cocoapods.org/pods/SDWebImage

Swift : My files in Firebase Storage wouldn't be deleted

I've got an application which allow user to save some picture on firebase Storage.
I'm trying to allow user to delete this files from the app, and so also to delete it from the storage.
My code :
if let user = Auth.auth().currentUser{
// user is connect
let storRef = Storage.storage().reference()
let userID = Auth.auth().currentUser?.uid
storRef.child("Planes").child(userID!).child(dataME[indexPath.row].image).delete(completion: nil)
self.tableView.reloadData()
dataME.remove(at: indexPath.row)
}else{
fatalError("⛔️ error ...")
}
Now in this case the line in my tableView is totally deleted with the other part of my code the database references is also deleted but the storage doesn't erase the picture ... Why ?
Thank's a lot for your help
Check if you get error when you delete storage
let storageRef = Storage.storage().reference().child("Planes").child(userID!).child(dataME[indexPath.row].image)
storageRef.delete { (error) in
if error != nil{
print(error)
return
}
// else proceed
}
You should not search by image.
Instead try using download URL that firebase supply
you can get the URL from the firebase dashboard by clicking on storage and than clicking on the current image, there you can see the download image.
when you upload an image it returns callback with URL, you have to save the URL on your data structure
upload image example:
func uploadImagePic(img1 :UIImage){
var data = NSData()
data = UIImageJPEGRepresentation(img1!, 0.8)! as NSData
// set upload path
let filePath = "\(userid)" // path where you wanted to store img in storage
let metaData = FIRStorageMetadata()
metaData.contentType = "image/jpg"
self.storageRef = FIRStorage.storage().reference()
self.storageRef.child(filePath).put(data as Data, metadata: metaData){(metaData,error) in
if let error = error {
print(error.localizedDescription)
return
}else{
//store downloadURL
let downloadURL = metaData!.downloadURL()!.absoluteString
data[index].downloadURL = downloadURL
}
}
}
// delete example
let storage = Storage.storage()
let url = data[index].downloadURL
let storageRef = storage.reference(forURL: url)
storageRef.delete { error in
if let error = error {
print(error)
} else {
// File deleted successfully
}
}

How to cache an array of Images fetched from firebase Storage using SDWebImage in Swift 4?

I am fetching images from firebase storage in the form of data and I want to cache the images in my app using SDWebImage. Please guide me how to achieve it?
for x in images_list{
let storageRef = storage.child("images/\(x).jpg")
storageRef.getData(maxSize: 1 * 1024 * 1024) { (data, error) in
if let error = error{
print(error.localizedDescription)
return
}
else{
imagesarray.append(UIImage(data: data!)!)
}
if let x = images_list.last{
cell.imageDemo.animationImages = imagesarray
cell.imageDemo.sd_setImage(with: storageRef) // Here I Want to cache the images of **imagesarray** that are being animated
cell.imageDemo.animationDuration = 2
cell.imageDemo.startAnimating()
}
}
}
you are downloading imageData directly from firebase in your question. Instead of using getData you will need to use downloadURL method. Like this:
for x in image_list {
let storageRef = storage.child("images/\(x).jpg")
//then instead of downloading data download the corresponding URL
storageRef.downloadURL { url, error in
if let error = error {
} else {
//make your imageArray to hold URL rather then images directly
imagesArray.append(url)
}
}
}
//////This is were you would use those url////////
let url = imageArray.first!
imageView.sd_setImage(with: url, completed: nil)
The most important part here is download url rather than image data. And whenever you set the image url to the imageView the SDWebImage library will cache it and display if already cached
Instead of getData method, I used downloadURL method and Cached the array of images.
var imagesarray = [URL]()
for x in images_list{
let storageRef = storage.child("images/\(x).jpg")
storageRef.downloadURL { (url, error) in
if let error = error{
print(error.localizedDescription)
}
else{
imagesarray.append(url!)
}
if let x = images_list.last{
cell.imageDemo.sd_setAnimationImages(with: imagesarray)
cell.imageDemo.animationDuration = 2
cell.imageDemo.startAnimating()
}
}
}