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.)
Related
I need to display the images that have been stored on the storage on Firebase. Right now, I only tracked the images using the link generated by function downloadURL:
func UploadImage(imageData: Data, path: String, completion: #escaping (String) -> ()){
let storage = Storage.storage().reference()
let uid = Auth.auth().currentUser?.uid
storage.child(path).child(uid ?? "").putData(imageData, metadata: nil) { (_, err) in
if err != nil{
completion("")
return
}
// Downloading Url And Sending Back...
storage.child(path).child(uid ?? "").downloadURL { (url, err) in
if err != nil{
completion("")
return
}
completion("\(url!)")
}
}
}
So all I can get is a hyperlink that is like: https://firebasestorage.googleapis.com/v0/b/getting-started-20f2f.appspot.com/o/profile_Photos%2FGQ1KR9H1mLZl2NAw9KQcRe7d72N2?alt=media&token=473ce86c-52ba-42ec-be71-32cc7dc895d7.
I refer to the official documentation, it seems that only when I have the name of the image file can I download it to an ImageView or UIImageView object. However, the link does not make any sense to me, so what can I do?
EDIT
I actually tried a solution provided by the official documentation:
func imageDownloader(_ imageURL: String) {
let store = Database.database().reference()
let uid = Auth.auth().currentUser?.uid
let imageRef = store.child(imageURL)
var myImageView = UIImageView()
imageRef.getData(completion: { (error, data) in
if let error = error {
// Uh-oh, an error occurred!
} else {
// Data for "images/island.jpg" is returned
let image = UIImage(data: data!)
}
})
}
But it suggests that I need to change something because Cannot convert value of type 'DataSnapshot' to expected argument type 'Data'.
If you're storing the image paths in Firestore, actually the exact file name does not matter if there is only one file available under the fork. So you just need to specify the path.
To then download the image from Storage, construct the path and download:
let uid = Auth.auth().currentUser?.uid
Storage.storage().reference().child("the\path\to\your\uid\collection").child(uid).getData(maxSize: 1048576, completion: { (data, error) in
if let data = data,
let img = UIImage(data: data) {
// do something with your image
} else {
if let error = error {
print(error)
}
// handle errors
}
})
You are uploading to Storage.storage(), but then in your imageDownloader, you're attempting to use Database.database(), which has a similar-looking API, but is, in fact, different.
Make sure to use Storage.storage() and that the closure parameters are in the order data, error in.
Finally, right now in your imageDownloader, it doesn't look like you're doing anything yet with var myImageView = UIImageView(), but keep in mind that you won't have access to the UIImage until the async getData completes.
Store your images at Firebase Storage & then retrieve using this code.
Storage.storage().reference.child("ProfilePhotos").child("ImageName").downloadURL {(url, _) in
DispatchQueue.main.async {
guard let url = url else { return }
imageView.setImage(with: url, placeholder: UIImage(named: "dummyImage"))
}
}
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";
}
Can I upload pdf files into firebase using Swift?.
If it is possible please share me the code.
I'm using the below code
let proofRef = filesstorgRef.child(timestamp)
let uploadTask = proofRef.putData(data, metadata: nil, completion: { (metadata, error) in
if error != nil {
//print("Failed to upload image:", error)
return
}
if let fileUrl = metadata?.downloadURL()?.absoluteString {
completion(fileUrl)
}
})
uploadTask.observe(.progress) { (snapshot) in
if (snapshot.progress?.completedUnitCount) != nil {
print("ImageUploadingPerCent=== \(String(describing: snapshot.progress?.completedUnitCount))")
}
}
uploadTask.observe(.success) { (snapshot) in
print("ImageUploading Success")
}
uploadTask.observe(.failure) { (snapshot) in
LoadingView.sharedInstance.visible(visible: false)
print("ImageUploading failure")
}
thanks in advance
// Get the default app firebse storage reference
let FIRStorage = Storage.storage()
// reference of the storage
let storageRef = FIRStorage.reference()
// You have to get the file URL from disk or anywhere
let filePath = Bundle.main.path(forResource: "mypdf", ofType: "pdf")
let filePathURL = URL(fileURLWithPath: filePath!)
// Create a reference/Path on firebase database, where you want to upload your file
let fileRef = storageRef.child("firebase path with filename")
// from this you cant upload the file on fileRef path
let uploadTask = fileRef.putFile(from: filePathURL, metadata: nil) { metadata, error in
guard let metadata = metadata else {
// error!
return
}
let metadataSize = metadata.size
// get the download url of this file
fileRef.downloadURL { (url, error) in
guard let downloadURL = url else {
// error!
return
}
}
}
Try this code.
I want to download a photo that was previously uploaded from Firebase. I am using the following code:
fbUser = Auth.auth().currentUser
let storage = Storage.storage()
let storageRef = storage.reference(forURL: "somepath.some")
let profilePicRef = storageRef.child(fbUser.uid+"_profile_pic.jpg")
var imageFB : UIImage? = nil
profilePicRef.downloadURL(completion: { (url, error) in
if error != nil {
print(error!)
return
}
URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
if error != nil {
print(error!)
return
}
guard let imageData = UIImage(data: data!) else { return }
DispatchQueue.main.async {
imageFB = imageData
}
}).resume()
})
The photo is there - if I delete the photo, then I get an error that the file is missing. However, after the download, imageFB is always equal to nil, even if the photo is there.
Any suggestions on how to fix that?
Firebase includes FirebaseUI, which helps managing image downloading / caching. Following the documentation, you should be able to download and display an image in a few simple lines of code.
I suggest you take a look at documentation. The link will take you to the image downloading section with an example on how to install and use it.
Try this let us know if works.
fbUser = Auth.auth().currentUser
let storage = Storage.storage()
let storageRef = storage.reference(forURL: "somepath.some")
let profilePicRef = storageRef.child(fbUser.uid+"_profile_pic.jpg")
// give your db ref var here
let ref = Database.database().reference()
let usersRef = ref.child("users").child(uid!)
var picArray: [UIImage]()
Download:
usersRef.observeEventType(.ChildAdded, withBlock: { (snapshot) in
// Get download URL from snapshot
let downloadURL = snapshot.value() as! String
profilePicRef.downloadURL(completion: { (url, error) in
let data = Data(contentsOf: url!)
let image = UIImage(data: data! as Data)
picArray.append(image)
})
})