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
}
}
Related
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
}
}
}
}
I have been building an app during the past month where you can upload your favorite memories. Each memory has a photo, date, short description, and place where it developed.
So the user was able to add memories, I did the following function for the photo part:
private func agregarRecuerdoFirebase() {
guard let imagenSeleccionada = self.imagen else {
print("No hay imagen")
return
}
guard let imagenData = imagenSeleccionada.jpegData(compressionQuality: 0.4) else {
return
}
let storageRef = Storage.storage().reference(forURL: "gs://chinahub-68043.appspot.com")
let storageRecuerdos = storageRef.child("recuerdos").child("recuerdoss")
let metadata = StorageMetadata()
metadata.contentType = "image/png"
storageRecuerdos.putData(imagenData, metadata: metadata) { (storageMetaData, error) in
if error != nil {
print(error?.localizedDescription)
return
}
}
Everything is working fine except the uploading to Firebase Storage. After uploading one photo to the storage, when I want to upload a second one it won't let me. Instead, the second image will replace the first one. How could I create a unique ID every time I want to add a new memory so that I could store it under that ID into the Storage?? Or is there another way for being able to achieve what I want??
try to replace below line in your project
let storageRecuerdos = storageRef.child("recuerdos").child("recuerdoss\(UUID().uuidString)\(Date().timeIntervalSince1970)")
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.
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()
}
}
}
Im working on a chat app using Firebase for storage and the realTime DB.
I have an userFriends tree in my DB where each user get his list of friends:
I have in storage each users profil photo , whats the best way/logic to download photos of the user's friends (to a local File with NSUrl/ in memory with NSData/ generate an URL) ,and more important to be updated if a friend modify his photo?
thanks for your help!
For storing the image
Parameters
infoOnThePicture:- info of the picture that you send from the UIImagePicker
completionBlock:- call when the uploading is complete
func profilePictureUploading(infoOnThePicture : [String : AnyObject],completionBlock : (()->Void)) {
if let referenceUrl = infoOnThePicture[UIImagePickerControllerReferenceURL] {
print(referenceUrl)
let assets = PHAsset.fetchAssetsWithALAssetURLs([referenceUrl as! NSURL], options: nil)
print(assets)
let asset = assets.firstObject
print(asset)
asset?.requestContentEditingInputWithOptions(nil, completionHandler: { (ContentEditingInput, infoOfThePicture) in
let imageFile = ContentEditingInput?.fullSizeImageURL
print("imagefile : \(imageFile)")
let filePath = FIRAuth.auth()!.currentUser!.uid + "/\(Int(NSDate.timeIntervalSinceReferenceDate() * 1000))/\(imageFile!.lastPathComponent!)"
//Creating a unique path for the image in FIRStorage
print("filePath : \(filePath)")
//Storing under the parent Node `ProfilePictures` in FIRStorage FIRControllerClass.storageRef.child("ProfilePictures").child(filePath).putFile(imageFile!, metadata: nil, completion: {
(metadata, error) in
if error != nil{
print("error in uploading image : \(error)")
//Show alert
}
else{
print("metadata in : \(metadata!)")
print(metadata?.downloadURL())
print("The pic has been uploaded")
print("download url : \(metadata?.downloadURL())")
self.uploadSuccess(metadata!, storagePath: filePath)
completionBlock()
}
})
})
}else{
print("No reference URL found!")
}
}
//Storing the filepath to NSUserDefaults
//Much better option would be to store the pictures filePath or storagePath in the FIREBASE DATABASE ITSELF WITH THE USERS DETAILS
//And retrieve that storagePath every time you wanna download the image(much sound option)
func uploadSuccess(metadata : FIRStorageMetadata , storagePath : String)
{
print("upload succeded!")
print(storagePath)
NSUserDefaults.standardUserDefaults().setObject(storagePath, forKey: "storagePath.\((FIRAuth.auth()?.currentUser?.uid)!)")
NSUserDefaults.standardUserDefaults().synchronize()
}
For retrieving the image
Parameters :-
UID:- userId
completion :- completionBlock for handling the completion for retrieval of your image
func retrieveStorageForUID( UID : String, completion : ((image : UIImage) -> Void) ){
print("initial storage")
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentDirectory = paths[0]
let filePath = "file:\(documentDirectory)/\(UID).jpg"
let filePath1 = "\(documentDirectory)/\(UID).jpg"
print(filePath)
print(filePath1)
//Again i am retrieving the storagePath from the NSUserDefaults but you can retrieve it from Firebase database if you stored it while uploading.
if let storagePath = NSUserDefaults.standardUserDefaults().objectForKey("storagePath.\(UID)") as? String {
print(storagePath)
FIRControllerClass.storageRef.child("ProfilePictures").child(storagePath).writeToFile(NSURL.init(string: filePath)!, completion: {(url, err) -> Void in
if err != nil{
self.delegate.firShowAlert("Error downloading", Message: "There was an error downloading your profile picture")
}else{
if let downloadedImage = UIImage(contentsOfFile: filePath1){
print("DOWNLOADED IMAGE :\(downloadedImage)")
self.profilePicture = downloadedImage
completion(image : self.profilePicture)
}
}
})
}else{
completion(image: UIImage(named: "defaultProfilePic")!)
//Default profile pic or Placeholder picture if there is no picture from the user...which you can also download from the FIRStorage..think
}
}
As for checking when your friends change their profile picture, you will replace users pic in the storage when user changes its profile pic, and store its link in the DB, and for knowing when did the user changed its profile pic, Use .observeEventType(.ChildChanged,.. which will notify you of the change at that location, and then update your UI asynchronously through dispatch_
PS:- Refer to the official sample example's of Firebase, You are looking for authentication in this project :https://github.com/firebase/quickstart-ios