How to store image from uiimageView in firebase - swift

func uploadImage(){
let data = Data()
let storage = Storage.storage()
let storageRef = storage.reference()
let imagesRef = storageRef.child(imageView.image) //not sure how it's done
let uploadTask = imagesRef.putData(data, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
return
}
let size = metadata.size
imagesRef.downloadURL { (url, error) in
guard let downloadURL = url else {
return
}
}
}
}
Hi,I'm new to xcode. I would love to know how to upload image displayed on uiimageview to firebase when the above function is called.

you can do something like this:
func uploadImage(img1 :UIImage){
var data = NSData()
data = UIImageJPEGRepresentation(img1!, 0.8)! as NSData
// setting the upload path
// then choose the path where you want to store the image in the storage
let filePath = "\(userid)"
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{
//Storing the downloadURL..
let downloadURL = metaData!.downloadURL()!.absoluteString
}
}
}

Related

How To Get a URL for a Video Saved in Firebase Storage

For starters here is what I currently have:
func uploadToCloud(fileURL: URL){
let storage = Storage.storage()
let data = Data()
let storageRef = storage.reference()
let localFile = fileURL
let photoRef = storageRef.child("\(email)\(counter)")
let uploadTask = photoRef.putFile(from: localFile, metadata: nil) { (metadata, err) in
guard let metadata = metadata else {
print(err?.localizedDescription)
return
}
To upload the video to storage ^
func playVideo(url: URL) {
let player = AVPlayer(url: url)
let vc = AVPlayerViewController()
vc.player = player
self.present(vc, animated: true) { vc.player?.play() }
}
This is what I have to play the video ^
Originally I tried also saving the link to Firestore, but all it saved was the files location, I believe on the phone which is not what I am trying to do. Is there a way to I can get a the url for the video saved in storage to run it as a url in the playVideo function?
Thank you!
Try this to get
// ....
photoRef.downloadURL { (url, error) in
if let error = error {
print("DEBUG: Upload: \(error.localizedDescription)")
return
}
guard let videoUrl = url?.absoluteString else {
print("DEBUG: Upload failed get URL")
return
}
completion(videoUrl)
}

Image size increases after upload it to Firebase Storage

I uploaded an image of size 7.4 MB to the firebase storage, but I got 24.8 MB. Why this happen? And how may I solve it?
Notice: I did not create any changes in the size of the image, I kept it as it is.
Here is the code:
func storeImageInFirebase(){
let storeageRef = Storage.storage().reference()
let imageName = UUID().uuidString + ".jpg"
let imagesReference = storeageRef.child("images").child(imageName)
let imageData = self.imgView.image!.pngData()
let metaData = StorageMetadata()
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
}
})
}
}
Try the below code. You can change maxCompression and maxFileSize to suit your needs. This will continue looping/compressing the file by increments of 0.05 while the image is bigger than your max size and while compression is higher than your max compression.
func storeImageInFirebase(image: UIImage) {
var compression: CGFloat = 0.9 //starting compression
let maxCompression: CGFloat = 0.05 //change to the maximum compression you want
let maxFileSize: Int = 512 * 512 //change to the maximum file size you want
guard var uploadImageData = image.jpegData(compressionQuality: compression) else {
print("ERROR: Creating photo data")
return
}
while (uploadImageData.count > maxFileSize) && (compression > maxCompression) {
compression -= 0.05
if let compressedImageData = image.jpegData(compressionQuality: compression) {
uploadImageData = compressedImageData
}
}
guard let uploadImageDataFinal = image.jpegData(compressionQuality: compression) else {
print("ERROR: Compressing final photo")
return
}
let imageName = UUID().uuidString
let storageRef = Storage.storage().reference().child("images").child(imageName)
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
storageRef.putData(uploadImageDataFinal, metadata: metadata) { (metadata, err) in
if err != nil {
print("ERROR: Adding photo to storage")
return
} else {
//success
print("SUCCESS: Photo uploaded")
return
}
}
}
To download image add this function to the view controller:
func getImage(handler: #escaping(_ image: UIImage?) -> ()) {
let imageName = UUID().uuidString
let storageRef = Storage.storage().reference().child("images").child(imageName)
storageRef.getData(maxSize: 27 * 1024 * 1024) { (data, error) in
if let data = data, let image = UIImage(data: data) {
print("SUCCESS: downloaded image")
handler(image)
} else {
print("ERROR downloading image. \(error)")
handler(nil)
}
}
}
When you need to download the image use:
self.getImage { (returnedImage) in
if let image = returnedImage {
//use image here
}
}

Having trouble understanding why my app crashes

I'm trying to upload an image to the Firebase storage. This is what I have so far:
fileprivate func uploadImageToFirebase(){
let storageRef = Storage.storage().reference()
guard let uploadData = imageToUpload?.pngData() else { return }
storageRef.putData(uploadData, metadata: nil) { (metadata, err) in
if err != nil {
print(err?.localizedDescription)
return
}
print(metadata)
}
}
uploadData is not nil, but my app crashes. this is what I get:
reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]'
I tried to look up, but couldn't understand why the app crash and how to fix it.
I got it that I'm trying to insert a nil, but I don't have anything nil.
I got it to work, this is what I have now:
fileprivate func uploadImageToFirebase(completion: #escaping((_ url: String?)->())){
let imageName = UUID().uuidString
let storageRef = Storage.storage().reference()
let imagesRef = storageRef.child(imageName)
guard let uploadData = imageToUpload?.jpegData(compressionQuality: 0.8) else { return }
let metaData = StorageMetadata()
metaData.contentType = "image/jpeg"
imagesRef.putData(uploadData, metadata: metaData) { (metadata, err) in
if err == nil && metadata != nil {
imagesRef.downloadURL(completion: { (url, err) in
guard let downloadUrl = url else { return }
let urlString = downloadUrl.absoluteString
completion(urlString)
})
}
completion(nil)
}
}
EDIT:
The problem with the code in the question was there was no name assigned to the file to upload. In other words
let storageRef = Storage.storage().reference()
is a reference to the storage itself, but when uploading to storage there needs to be a filename like this
let storageRef = Storage.storage().reference()
let myFile = storageRef.child("my_cool_pic.jpg")
and the use is
myFile.putData(uploadData, metadata: nil)...

Trying to return downloadUrl from Firebase storage using a function

I'm trying to create a function that uploads images to Firebase Storage and returns the download url for their path so I can use it other parts of the app.
This is what the function looks like:
func uploadImage(to reference:StorageReference, image:UIImage) -> URL? {
let imageData = UIImageJPEGRepresentation(image, 0.2)
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
var downloadURL = metadata.downloadURL()
reference.putData(imageData!, metadata: metadata) { (metadata, error) in
if error != nil {
print("Couldnt upload due to \(String(describing: error))")
}
downloadURL = metadata?.downloadURL()
}
return downloadURL!
}
I can't seem to get the result that I want as downloadUrl always returns nil. What am I doing wrong?
The problem here is that your function is returning before the upload is complete. In other words your function needs to return a callback, rather than a plain URL. Something like -
func uploadImage(to reference:StorageReference, image:UIImage, completion: #escaping (URL?) -> Void) {
let imageData = UIImageJPEGRepresentation(image, 0.2)
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
var downloadURL = metadata.downloadURL()
reference.putData(imageData!, metadata: metadata) { (metadata, error) in
if error != nil {
print("Couldnt upload due to \(String(describing: error))")
completion(nil)
} else {
if let downloadUrl = metadata?.downloadURL() {
completion(downloadUrl)
} else {
completion(nil)
}
}
}
}

Swift 3 - How to download Profile Image from FireBase Storage

I need help on retrieving Image from firebase storage, i learned how to save it but cant download it to current user profile.
here is my code so far:
FIRAuth.auth()?.createUserWithEmail(email!, password: password!, completion: { (authData, error) in
if error == nil {
if (password == "" || name == "" || email == "") {
self.showAlert("error", message: " Please Fill In The Blank")
}
if (password != confirm_password) {
self.showAlert("ERROR", message: "Password Don't Match")
}
}
else {
self.showAlert("ERROR", message: "Please Try Again")
}
let filePath = "\(FIRAuth.auth()!.currentUser!.uid)/\("userPhoto")"
var data = NSData()
let metaData = FIRStorageMetadata()
//let imageName = NSUUID().UUIDString
let storageRef = FIRStorage.storage().referenceForURL("gs://storageURL")
storageRef.child(filePath).putData(data, metadata: metaData){(metaData,error) in
if let error = error {
print(error.localizedDescription)
return
}
if let ProfileImageUrl = metaData?.downloadURL()?.absoluteString {
let values : [String : AnyObject] = ["name": name!, "email": email!, "profileImageUrl": ProfileImageUrl]
self.userPost(values)
}
}
})
}
//save data in Database
func userPost(values: [String: AnyObject]) {
let ref = FIRDatabase.database().referenceFromURL("https://databaseURL.firebaseio.com/")
ref.child("users").childByAutoId().setValue(values)
}
so i got that so far but cant figure out how to download it to user profile.
here is my code for user ProfileVC:
#IBOutlet weak var ProfileImg: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.retriveData()
ProfileImg.image = UIImage(named: "ic_account_circle.png")
imagePicker.delegate = self
}
func DownloadProfilePhoto() {
let storageRef = FIRStorage.storage().referenceForURL("gs://StorageURL.com")
let filePath = "\(FIRAuth.auth()!.currentUser!.uid)/\("userPhoto")"
}
Please Help.....
You need to download the image data, and then create an image. You should try this:
let storage = FIRStorage.storage()
var reference: FIRStorageReference!
reference = self.storage.referenceForURL("gs://appname.appspot.com/filePath")
reference.downloadURLWithCompletion { (url, error) in
let data = NSData(contentsOfURL: url!)
let image = UIImage(data: data!)
ProfileImg.image = image
}
You should check the Firebase documentation https://firebase.google.com/docs/storage/ios/download-files
For people looking for swift 4
let storage = Storage.storage()
var reference: StorageReference!
reference = storage.reference(forURL: "gs://appname.appspot.com/filePath")
reference.downloadURL { (url, error) in
let data = NSData(contentsOf: url!)
let image = UIImage(data: data! as Data)
cell.imgOutlet.image = image
}