When uploading a 10.79 MB image from my application to Firebase Storage it takes about 6-8 seconds to complete which seems extremely long. Is it because the image is too large or am I doing something wrong in code? Here is my code:
func storeImage(pickedImage: Any){
let username: String = Utilities.userAttributes.username
let storageRef = storage.reference()
let profileImageRef = storageRef.child("images/" + username + ".jpg")
let imageData: Data = (pickedImage as! UIImage).pngData()!
// Upload the file to the path "images/rivers.jpg"
let uploadTask = profileImageRef.putData(imageData, metadata: nil) { (metadata, error) in
guard metadata != nil else {
print("error uploading")
return
}
}
uploadTask.observe(.progress) { snapshot in
// Upload reported progress
let percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
/ Double(snapshot.progress!.totalUnitCount)
print(percentComplete)
}
}
Any help would be greatly appreciated, thank you.
Related
I have been using the firebase guides to upload a user image to firebase storage but after I upload the user image nothing appears in the folder. How do I solve this problem to successfully upload my image to firebase storage is there anything i'm missing ?
Size 0 bytes
let storage = Storage.storage()
let storageRef = storage.reference()
let image = UIImage(named: "ProfileImage")
let data = Data()
let starsRef = storageRef.child("ProfileImage.jpeg")
let metadata = StorageMetadata()
metadata.contentType = "ProfileImage/jpeg"
let uploadTask = starsRef.putData(data, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
return
}
let size = metadata.size
starsRef.downloadURL { (url, error) in
guard let downloadURL = url else {
return
}
}
}
Here is 6 steps on how to upload the image to Firebase Storage and retrieve the URL path for later usage.
Create an unique name using UUID().uuidString
Compress the image into compressionQuality
Sat the metaData as .jpeg
Add the data to Firebase Storage
If succeeded, retrieve the image URL
Convert the URL to url?.absoluteString and print it out using print
//1. Create an unique name for your image
let imageName = UUID().uuidString
let imageReference = Storage.storage().reference().child(imageName)
//2. Compress quality
if let uploadData = self.tempImageView.image!.jpegData(compressionQuality: 0.5){
//3. Save image as .jpeg
let metaDataForImage = StorageMetadata()
metaDataForImage.contentType = "image/jpeg"
//4. Add the data to Firebase Storage
imageReference.putData(uploadData, metadata: metaDataForImage) { (meta, err) in
if let err = err{
print(err.localizedDescription)
}
else{
//5. Retrieving the image URL
imageReference.downloadURL { (url, err) in
if let err = err{
print(err.localizedDescription)
}
else{
//6. Print the complete URL as string
let urlString = url?.absoluteString
print(urlString)
}
}
}
}
}
Make that let data a guard let data, that way you won't have to force-unwrap when you need it to be non-optional. I'd say generally avoid force-unwrapping in general.
The contentType should be image/jpeg. I googled some piece codes, it shows the same concept.
About contentType, more detail at this wiki link.
If you upload an image with jpeg format, then you should upload jpeg binary. But data = image.pngData(), it seems to be the binary data of png.
// data is `png` binary
let data = image.pngData()
// imageData is `jpeg` binary
let imageData = image.jpegData(compressionQuality: 0.9)
let uiImage: UIImage = UIImage(data: imageData!)!
let starsRef = storageRef.child("ProfileImage.jpg")
let metadata = StorageMetadata()
// About contentType
// See it: https://en.wikipedia.org/?title=Content_type&redirect=no
metadata.contentType = "ProfileImage/jpeg"
// data is `png` binary, but contentType is `jpeg` ?
let uploadTask = starsRef.putData(data!, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
return
}
Issue with Firebase storage for image uploads: “Storage bucket cannot be initialised with a path”
Occurs when we try when pulling the putData method
We tried the following:
storage.storage().reference().child("Images").child("image1.jpg")
reference().document(object.id).setData(data,merge:true)
storage.storage().reference().child("Images").child("image1.jpg")
reference().document(object.id).setData(data,merge:true)
I understand that you have trouble storing the image, try this way
let imageName = "image1.jpg"
let image = UIImage(named: imageName)
let store = Storage.storage()
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
let imageData: Data = UIImageJPEGRepresentation(image, 0.5)!
let storeRef = store.reference().child("Images")
let _ = storeRef.putData(imageData, metadata: metadata) { (metadata, error) in
guard let _ = metadata else {
print("error occurred: \(error.debugDescription)")
return
}
let pat = (metadata?.downloadURL()?.absoluteString.description)
let link = pat! //Link of image
}
Just ran into this Error message, took me a few hours because it crashes the app every time. Previously, I initialized my bucket for dev and prod using the full path, prefixed by gs://
Removed the gs:// and that fixed the problem:
Changed:
if (Config.of(context).isDev) {
FirebaseStorage.instance.bucket = "gs://dev-appname.appspot.com";
} else {
FirebaseStorage.instance.bucket = "gs://appname.appspot.com";
}
TO:
if (Config.of(context).isDev) {
FirebaseStorage.instance.bucket = "dev-appname.appspot.com";
} else {
FirebaseStorage.instance.bucket = "appname.appspot.com";
}
I have an app where you can upload videos to firebase. The problem I have recently encountered is that all videos uploaded to firebase are 0 sec long (This is when in the DB, before, as in in the app, they are of correct length), which is of course wrong.
Some things I've tried:
I check how I upload which i also included bellow and it seems correct.
thumbnail is of type UIImage
The video right before I send it (in the preview I have in-app) the video looks perfect.
Another thing I noticed is that a thumbnail I upload with the video which is an image is being uploaded as a video.
} else if let vidData = media.videoURL {
print("VIDEO")
let autoIDSto = "media\(media.numMedia).mov"
print(autoIDSto)
let autoID = "media\(media.numMedia)"
let storageRef = Storage.storage().reference().child((Auth.auth().currentUser?.uid)!).child("post:\(postID)").child(autoIDSto)
let postRef = childRef.child("Media")
let uploadData = media.videoURL
let uploadTask = storageRef.putFile(from: vidData, metadata: nil) { (metadata, error) in
print("\(vidData) : Video data")
guard let metadata = metadata else { return }
if let error = error {
print(error)
}
storageRef.downloadURL(completion: { (url, error) in
//a bunch of code to add to DB
if let thumbnailImageData = media.thumbnailImage!.jpegData(compressionQuality: 1.0) {
storageRef.putData(thumbnailImageData, metadata: nil) { (metadata, error) in
storageRef.downloadURL(completion: { (url, error) in
if let thumbnail = url {
mediaRef.updateChildValues(["thumbnail" : "\(thumbnail)"])
Whats wrong and how can I fix it?
You use the same path ( 1 with mov extension )
let storageRef = Storage.storage().reference().child((Auth.auth().currentUser?.uid)!).child("post:\(postID)").child(autoIDSto)
to store the video/image thumbnail here
let uploadTask = storageRef.putFile(from: vidData, metadata: nil) { (metadata, error) in
and
storageRef.putData(thumbnailImageData, metadata: nil) { (metadata, error) in
There should be 2 different paths 1 with mov extension and another with jpg extension that you finally store the reference of both in 1 record in your database table
I am trying to upload an image from ImageView to Firebase storage but it won't work.
I have listed my code below: My image view is called ProfileImage
let storageRef = Storage.storage().reference().child("myImage.png")
if let uploadData = self.ProfileImage.image!.pngData() {
storageRef.putFile(from: uploadData, metadata: nil) { (metadata, error) in
if error != nil {
print("error")
completion(nil)
} else {
// your uploaded photo url.
}
}
}
It comes up with the error "Cannot convert value of type 'Data' to expected argument type 'URL'
You are trying to upload Data, not a file. Replace
putFile
With
putData
And it should work fine
Try this code :-
let storageRef = Storage.storage().reference().child("myImage.png")
if let uploadData = UIImagePNGRepresentation(self.profileImage.image!) {
storageRef.put(uploadData, metadata: nil) { (metadata, error) in
if error != nil {
print("\(error.localizeDescription)")
} else {
// your uploaded photo url.
}
}
let refDatabase = Database.database().reference()
var refstorage = Storage.storage().reference()
let data = image.jpegData(compressionQuality: 1.0) //
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
let postkey = refDatabase.child("Post").childByAutoId().key
print(postkey)
let imagename = "PostImage/\(postkey).png"
refstorage = refstorage.child(imagename)
let timestamp = Date().timeIntervalSince1970 // you can use this to track time when it was uploaded.
self.refstorage?.putData(data!, metadata: metadata, completion: { (meta, error) in
if error == nil{
if let imageData = meta?.downloadURL()?.absoluteString{
// DO SOMETHING
} else {
print("Couldn't get the URL for image")
}
}
})
I know that this question has been answered, but there is an easier way to do this. Along with import Firebase and Firebase Storage, you will also have to add FirebaseUI to your podfile and import it.
After you have done that, you could get your image to your app much simpler.
let storage = Storage.storage()
let storageRef = storage.reference()
let placeholderImage = UIImage(named: "placeholder.jpeg")
let reference = storageRef.child("myImage.png")
ProfileImage.sd_setImage(with: reference, placeholderImage: placholderImage)
(The placeholder Image would just be a transparent image that you put in your assets folder in XCode that you could reuse multiple times in your application, for whenever you needed to get a Firebase Image on your app.)
Before writing question I would say that I'm new in iOS development and in firebase too :) That's why I apologize in advance for a silly question :)
When I load profile.png image from firebase storage programmatically it's loaded correctly without any problems.
static func getUserImage(_ uid: String, completion: #escaping (UIImage?, NSError?) -> Void) {
// Create a reference to the file you want to download.
let storage = FIRStorage.storage()
let userUID: String = String(describing: uid)
let storageRef = storage.reference(forURL: "...some address...")
let downloadRef = storageRef.child("\(userUID)/profilePhoto.png")
// Download in memory with a maximum allowed size of 10MB (10 * 1024 * 1024 bytes).
downloadRef.data(withMaxSize: 10 * 1024 * 1024) {
data, error in
guard let data = data, error == nil else {
NSLog("Retrieve image failed:\n\(error?.localizedDescription)")
completion(nil, error as! NSError)
return
}
guard let image = UIImage(data: data) else {
NSLog("Image decoding failed:\n\(data)")
completion(nil, nil)
return
}
assert(error == nil)
completion(image, nil)
}
}
But when I go to firebase storage in browser and try to search it by uid manually from list I can't find it - it doesn't exist. Could you explain me how it's possible? It problem exists only for several images in firebase storage.
Thank you in advance!
Folder name should start with capital letter.