Swift4 : Download photo from Firebase - ios

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)
})
})

Related

Display Image downloaded from downloadURL generated by Firebase

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"))
}
}

ImageView to Firebase Storage in Swift

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.)

How to upload pdf file into firebase by using iOS

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.

How to get rid of the word optional before a url saved in firebase?

Currently I am saving the url of images stored in the firebase database. However I am getting the word optional before the url. As seen bellow.
"Optional(https:URL.HERE)"
The following is the code block where the saving happens:
if let imageData = UIImageJPEGRepresentation(image, 0.8) {
let metadata = storageRef //.child("poop/")
let uploadTask = metadata.putData(imageData, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
// Uh-oh, an error occurred!
return
}
// You can also access to download URL after upload.
storageRef.downloadURL { (url, error) in
guard let downloadURL = url else {
// Uh-oh, an error occurred!
return
}
let imgURL = url
//database integration
let ref = Database.database().reference()
let usersRef = ref.child("usersPosts")
let uid = Auth.auth().currentUser?.uid
let newUserRef = usersRef.child(uid!)
//creates a child for email and password (i think we shud store password so we can tell sumone what it is inmediatly, maybe)
newUserRef.setValue(["Image": "\(imgURL)"])
}
}
// For progress
uploadTask.observe(.progress, handler: { (snapshot) in
guard let progress = snapshot.progress else {
return
}
let percentage = (Float(progress.completedUnitCount) / Float(progress.totalUnitCount))
progressBlock(Double(percentage))
})
} else {
completionBlock(nil, "Image could not be converted to Data.")
}
You are getting Optional... because imgURL is optional. And imgURL is optional because you assigned it from url which is optional.
Since you already unwrapped url in the guard statement, just use downloadURL instead of creating imgURL.
Remove:
let imgURL = url
And replace the use of imgURL with downloadURL which is the properly unwrapped version of url from the guard.
newUserRef.setValue(["Image": "\(downloadURL)"])

How to retrieve url from firebase database and show url as a image in imageview (SWIFT)?

I m trying to get Url of image from firebase database and show that url as a image in imageview (iOS).
below is the image of database
How can I do so?
I just started with Xcode, any help will be much appreciated
func showImage() {
Database.database().reference().child("Images").child("abcd").observeSingleEvent(of: .value, with: { snapshot in
if let url = snapshot.value as? String {
URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in
if error == nil {
let image = UIImage(data: data!)
imageView.image = image
}
}.resume()
}
})
}

Resources