Firebase image upload with swift - ios

When i run code, completion handler block does not working.When line work mediaFolder.child(userId!).putData(data, metadata: nil) { (metadata, error) in image file upload in storage but code does not running in block. This is my code :
if let data = self.profileImage.image?.jpegData(compressionQuality: 0.5)
{
mediaFolder.child(userId!).putData(data, metadata: nil) { (metadata, error) in
if error != nil {
// errror
}
else {
//enter code here
}
}

Please see below code to upload image data to Storage and get the download url
var imgData: NSData = NSData(data: UIImageJPEGRepresentation((self.img_Photo?.image)!, 0.5)!)
self.uploadProfileImageToFirebase(data: imgData)
func uploadProfileImageToFirebase(data:NSData){
let randomPic = parentVC?.randomString(length: 10)
let storageRef = Storage.storage().reference().child("Profile_Pics").child("\(userId ?? randomPic).jpg")
if data != nil {
storageRef.putData(data as Data, metadata: nil, completion: { (metadata, error) in
if(error != nil){
print(error)
return
}
guard let userID = Auth.auth().currentUser?.uid else {
return
}
// Fetch the download URL
storageRef.downloadURL { url, error in
if let error = error {
// Handle any errors
if(error != nil){
print(error)
return
}
} else {
// Get the download URL for 'images/stars.jpg'
let urlStr:String = (url?.absoluteString) ?? ""
print(urlStr)
}
}
})
}

Related

I want to pick video from Imagepicker then I want to send video in firebase and retrieve it

I want to pick video from Images Picker then I want to send video in firebase and retrieve it Please provide code in swift 5, i write code also for sending video on firebase
func downloadImages(folderPath:String,success:#escaping (_ image:UIImage)->(),failure:#escaping (_ error:Error)->()){
// Create a reference with an initial file path and name
let reference = Storage.storage().reference(withPath: "\(folderPath)")
reference.getData(maxSize: (1 * 1024 * 1024 * 1024 * 1024 * 1024)) { (data, error) in
if let _error = error{
print(_error)
failure(_error)
} else {
if let _data = data {
let myImage:UIImage! = UIImage(data: _data)
success(myImage)
}
}
}
}
Upload video On firebase Storage is
func upload(file: URL, completion: #escaping ((_ url : URL?) -> ())) {
let name = "\(Int(Date().timeIntervalSince1970)).mp4"
do {
let data = try Data(contentsOf: file)
let storageRef =
Storage.storage().reference().child("Videos").child(name)
if let uploadData = data as Data? {
let metaData = StorageMetadata()
metaData.contentType = "video/mp4"
storageRef.putData(uploadData, metadata: metaData
, completion: { (metadata, error) in
if let error = error {
completion(nil)
}
else{
storageRef.downloadURL { (url, error) in
guard let downloadURL = url else {
completion(nil)
return
}
completion(downloadURL)
}
print("success")
}
})
}
}catch let error {
print(error.localizedDescription)
}
}
and Get Video From firebase
let reference = Storage.storage().reference().child("Videos").child(folderPath)
reference.getData(maxSize: INT64_MAX) { (data, error) in
if let error = error {
print("Error downloading image data: \(error)")
return
}
reference.getMetadata(completion: { (metadata, metadataErr) in
if let error = metadataErr {
print("Error downloading metadata: \(error)")
return
}
else {
reference.downloadURL { URL, error in
completion(URL)
print(URL)
}

Not able to get the url of uploaded image on firebase storage

class FCMStorage {
var storage: Storage!
init() {
storage = Storage.storage()
}
func storeImage(data: Data?, name: String, completion: #escaping ((String?, Error?)->Void)) {
guard let data = data else {
return
}
let metaData = StorageMetadata()
metaData.contentType = "image/jpeg"
let path = "images/" + name
print("img to store = \(path)")
let ref = storage.reference()
let uploadTask = ref.child(path).putData(data, metadata: metaData) { (metadata, error) in
if error == nil {
print(metadata as Any)
ref.downloadURL(completion: { (url, error) in
completion(url?.absoluteString, error)
})
} else {
print("storeImage error: \(error!)")
}
}
uploadTask.observe(.progress) { (snapshot) in
print((snapshot.progress?.fractionCompleted ?? 0) * 100.0)
if snapshot.status == .success || snapshot.status == .failure {
uploadTask.removeAllObservers(for: .progress)
}
}
}
}
Using the able class I am able to upload the image on firebase successfully and I am able to see the uploaded image on the firebase too but...
When I call downloadURL() method it always giving me the following error
ref.downloadURL(completion: { (url, error) in
completion(url?.absoluteString, error)
})
Error: Failed to retrieve a download URL.
Anyone could help me out on this issue!!
EDIT
When I print metadata of the file it prints the following....
FIRStorageMetadata 0x283f99860: {
bucket = "sportoilic.appspot.com";
contentDisposition = "inline; filename*=utf-8''8E13A816-FAF1-47ED-8F84-94BBB8C4C77F";
contentEncoding = identity;
contentType = "application/octet-stream";
generation = 1601287237056536;
md5Hash = "VgMH6NMPGJT//LCD8goaDA==";
metageneration = 1;
name = "8E13A816-FAF1-47ED-8F84-94BBB8C4C77F";
size = 114787;
timeCreated = "2020-09-28T10:00:37.056Z";
updated = "2020-09-28T10:00:37.056Z";
}
and after that when I try to get the download url for the uploaded image< I am getting the above mentioned error(Error: Failed to retrieve a download URL).
What is the issue? Am I missing something here?
After trial and error of several hours, finally got the solution.
class FCMStorage {
var ref: StorageReference!
init(path: String) {
ref = Storage.storage().reference(withPath: path)
print("img to store at path = \(path)")
}
func storeImage(data: Data?, completion: #escaping ((String?, Error?)->Void)) {
guard let data = data else {
return
}
let uploadTask = ref.putData(data, metadata: nil) { (metadata, error) in
if error == nil {
print(metadata as Any)
self.ref.downloadURL(completion: { (url, error) in
completion(url?.absoluteString, error)
})
} else {
print("storeImage error: \(error!)")
}
}
uploadTask.observe(.progress) { (snapshot) in
print((snapshot.progress?.fractionCompleted ?? 0) * 100.0)
if snapshot.status == .success || snapshot.status == .failure {
uploadTask.removeAllObservers(for: .progress)
}
}
}
}
So store image just need to call like this...
let path = "images/" + UUID().uuidString
FCMStorage(path: path).storeImage(data: data) { (imgUrl, error) in
if let strUrl = imgUrl, error == nil {
FCMDatabase.init(OfTable: .chatRooms).setImageUrl(strUrl: strUrl, teamId: self.team?.id ?? 0, forMsgId: self.arrChats.last?.messageId ?? "") { (isDone) in
if isDone {
print("Image url set in database")
}
}
} else {
print("Error: \(error?.localizedDescription ?? "Error while getting image url")")
}
}

How to upload an array of images in Firebase Storage using iOS Swift

I want to upload an array of images by user
This is the code when i am uploading a single image to firebase storage refer Code: 1. but i am having problem when i am uploading and array of image. Refer code: 2
Code: 1
func uploadImage(image:UIImage,userId:String,completion:#escaping(_ status:Bool,_ response:String)->Void){
// if status is true then downloadurl will be in response
// Data in memory
guard let data = image.jpegData(compressionQuality: 0.2) else{
completion(false,"Unable to get data from image")
return
}
// Create a reference to the file you want to upload
let riversRef = firebaseStorage.reference().child("images/\(userId).jpg")
// Upload the file to the path "images/rivers.jpg"
let _ = riversRef.putData(data, metadata: nil) { (metadata, error) in
guard let _ = metadata else{
// Uh-oh, an error occurred!
completion(false,error!.localizedDescription)
return
}
// You can also access to download URL after upload.
riversRef.downloadURL { (url, error) in
guard let downloadURL = url else{
// Uh-oh, an error occurred!
completion(false,error!.localizedDescription)
return
}
completion(true,downloadURL.absoluteString)
}
}
}
Code: 2
func uploadPostImages(image:[UIImage],userId:String,completion:#escaping(_ status:Bool,_ response:String)->Void){
let photoDictionary = ["postImages": PostArray.sharedInstance.photosArray as NSArray]
// Create a reference to the file you want to upload
let riversRef = firebaseStorage.reference().child("postImages/\(userId).jpg")
// Upload the file to the path "images/rivers.jpg"
let _ = riversRef.putData(photoDictionary, metadata: nil) { (metadata, error) in
guard let _ = metadata else{
// Uh-oh, an error occurred!
completion(false,error!.localizedDescription)
return
}
// You can also access to download URL after upload.
riversRef.downloadURL { (url, error) in
guard let downloadURL = url else{
// Uh-oh, an error occurred!
completion(false,error!.localizedDescription)
return
}
completion(true,downloadURL.absoluteString)
}
}
}
I am getting this error in code: 2
Cannot convert value of type '[String : NSArray]' to expected argument type 'Data'
anyone who can help me??
To my knowledge something like this should work. Sorry, I am not at an IDE. If this doesn't work leave a comment and I will take a closer look.
func uploadImages(
images:[UIImage],
userId:String,
completion:#escaping(_ status:Bool,_ response:String)->Void)
{
images.enumerated().forEach { (index, image) in
guard let data = image.jpegData(compressionQuality: 0.2) else{
completion(false,"Unable to get data from image")
return
}
// Create a reference to the file you want to upload
let riversRef = firebaseStorage.reference().child("images/\(userId)\(index).jpg")
// Upload the file to the path "images/rivers.jpg"
let _ = riversRef.putData(data, metadata: nil) { (metadata, error) in
guard let _ = metadata else{
// Uh-oh, an error occurred!
completion(false,error!.localizedDescription)
return
}
// You can also access to download URL after upload.
riversRef.downloadURL { (url, error) in
guard let downloadURL = url else{
// Uh-oh, an error occurred!
completion(false,error!.localizedDescription)
return
}
completion(true,downloadURL.absoluteString)
}
}
}
}
This code will upload an array of images
func uploadImages(images:[UIImage], userId:String, completion:#escaping(_ status:Bool, _ response:String)->Void){
guard images.count <= 5 && !images.isEmpty else {return}
convertImagesToData(images: images).enumerated().forEach { (index, image) in
let riversRef = firebaseStorage.reference().child("userAdPostImages/\(userId)\(index).jpg")
let _ = riversRef.putData(image, metadata: nil, completion: { (_ , error) in
if let error = error {
completion(true, error.localizedDescription)
return
}
riversRef.downloadURL(completion: {(url, error) in
if let error = error{
completion(true,error.localizedDescription)
return
}
guard let downloadURL = url else {return}
completion(false,downloadURL.absoluteString)
})
})
}
}
and this will add your post to firebase including array images
func addPost() {
hud.show()
dispatchGroup.enter()
let user = Auth.auth().currentUser
if let user = user {
self.userId = user.uid
}
let location = self.locationTextfield.text ?? ""
let type = self.selectedType ?? ""
let description = self.descriptionTextView.text ?? ""
let adImages = self.adImages
let userId = self.userId ?? ""
let price = priceTextfield.text ?? ""
let userName = self.userName ?? ""
let userProfileImage = self.userProfileImage ?? ""
let userphoneNumber = self.phoneNumber ?? ""
ServerManager.sharedDelegate.uploadImages(images: adImages, userId: userId) { (isError, urlString) in
guard !isError else {
DispatchQueue.main.async {
hud.hide()
}
return
}
self.imagePaths.append(urlString)
print("This is the image path saved \(self.imagePaths)!!!!")
if self.imagePaths.count == adImages.count {
self.dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .global(qos: .background), execute: {
ServerManager.sharedDelegate.addPost(UserProfileImage: userProfileImage, UserName: userName, phoneNumber: userphoneNumber, adImages: self.imagePaths, Price: price, location: location, type: type, Description: description) { _ , message in
DispatchQueue.main.async {
hud.hide()
self.vc?.view.makeToast(message)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.vc?.dismiss(animated: true, completion: nil)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
}
}
return
}
})
}
Thanks to #MichaelWells for help and sorry for late posting the answer
You can encode the dict and then store it as data:
let data = JSONEncoder().encode(photoDictionary)

Firebase putData function

I am using Xcode, Swift 3.
I am trying to call putData for an image (PNG), and this is my code :
let storageRef = Storage.storage().reference().child("ProductsImages").child(product.UniqueID()).child("MainImage.png")
if let mainChosenImage = self.selectedImageToUpload
{
if let uploadData = UIImagePNGRepresentation(mainChosenImage)
{
storageRef.putData(uploadData, metadata: nil, completion:
{
(StorageMetaData, error) in
if error != nil
{
print(error)
return
}
self.mainImageURL = StorageMetaData?.downloadURL()?.absoluteString
})
}
}
And the behavior is this - the image is saved fine to Firebase, but "completion" isn't called. Meaning - it won't check if error != nil, and more importantly - it won't instantiate mainImageURL with the absolute URL string.
Any ideas on how to fix this ?
completion should look like this
if let uploadData = UIImagePNGRepresentation(self.myImageView.image!) {
storageRef.put(uploadData, metadata: nil) { (metadata, error) in
if error != nil {
print("error")
} else {
// your uploaded photo url.
}
}

Why code block is never called?

I have function to put photos to Firebase Storage:
func SendAdvertisesToFireBase(_ data: SkelbimasModel) {
var links = [String]()
for image in data.nuotraukos {
print(image)
if let uploadData = UIImagePNGRepresentation(image) {
//let imageNames = NSUUID().uuidString
let store = Storage.storage().reference().child("images").child("image.png")
store.putData(uploadData, metadata: nil, completion: { (metadata, error) in
if (error != nil) {
print(error as Any)
print("nepaejo")
return
}
print("paejo")
let address = metadata?.downloadURL()?.absoluteString
links.append(address!)
})
}
}
self.AddDataAfterImageAdded(self.skelbimas, links)
}
print(image) prints an image.
let store =Storage.storage().reference().child("images").child("image.png" in debugger shows that got a reference, but store.putData(...) is not called. I've got no errors.

Resources