I'm having trouble getting my image to download in from user input. Whenever I try to upload the image I get the error screen. I'm working in Xcode 9 with swift 4.0.
if let imgData = UIImageJPEGRepresentation(img, 0.2){
let imgUid = NSUUID().uuidString
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
let storageItem = Storage.storage().reference().child(imgUid)
storageItem.putData(imgData, metadata: metadata) { (metadata, error) in
if error != nil {
print("Couldn't Upload Image")
} else {
print("Uploaded")
storageItem.downloadURL(completion: { (url, error) in
if error != nil {
print(error!)
return
}
if url != nil {
self.setUser(img: url!.absoluteString)
}
}
)
}
}
}
Related
I'm trying to upload a video file using phpickerviewcontroller, but I'm running into an issue uploading the URL to FirebaseStorage. Here is some code:
func uploadVideo(videoURL: URL)
{
let storage = Storage.storage()
let storageRef = storage.reference()
let videoRef = storageRef.child("rPosts/\(uid!)/\(fileID)")
let metadata = StorageMetadata()
metadata.contentType = "video/quicktime"
var videoData: Data = Data()
do
{
videoData = try Data(contentsOf: videoURL)
}
catch
{
print(error.localizedDescription)
return
}
videoRef.putData(videoData, metadata: metadata)
{ (metaData, error) in
guard error == nil else
{
self.errorLabel.text = error!.localizedDescription
return
}
}
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult])
{
dismiss(animated: true, completion: nil)
guard let itemProvider = results.first?.itemProvider else { return }
itemProvider.loadItem(forTypeIdentifier: "com.apple.quicktime-movie", options: nil)
{ (videoFile, error) in
guard error == nil else { return }
let videoFile = videoFile as? URL
DispatchQueue.main.async
{
self.uploadVideo(videoURL: videoFile!)
print(videoFile!)
}
self.uploadedYet = true
}
}
I've tried using .putFile but it keeps on saying
Ensure file URL is not a directory, symbolic link, or invalid url.
When I use .putData it says
The file "..." couldn’t be opened because there is no such file
EDIT:
itemProvider.loadFileRepresentation(forTypeIdentifier: "com.apple.quicktime-movie")
{ (videoURL, error) in
guard error == nil else { return }
print("isbeingcalled") //does not get calleed :(
DispatchQueue.main.async
{
let storageRef = Storage.storage().reference()
let videoRef = storageRef.child("rPosts/\(self.uid!)/\(self.fileID).mov")
let metadata = StorageMetadata()
metadata.contentType = "video/quicktime"
print("run")
videoRef.putFile(from: videoURL!, metadata: metadata)
{ (metaData, error) in
guard error == nil else
{
print(videoURL!)
print(videoRef.fullPath)
self.errorLabel.text = error!.localizedDescription
print(error!.localizedDescription)
return
}
}
}
self.uploadedYet = true
}
I'm new to firebase and I'm facing a problem here.
I have successfully uploaded my image to firebase storage already, however, I need to get the downloadurl at once and post it to the database. And I'm not sure why it doesn't work within that closure.
The following is my code:-
func CreateNewChatRoom(user: User, caption: String, data: Data){
let filePath = "\(user.uid)/\(Int(NSDate.timeIntervalSinceReferenceDate)).jpg"
let metaData = StorageMetadata()
metaData.contentType = "image/jpg"
let reference = storageRef.child(filePath)
reference.putData(data, metadata: metaData) { (metadata, error) in
if let error = error {
print("\(error.localizedDescription)")
return
}
reference.downloadURL(completion: { (url, error) in
if let error = error{
print("Error : \(error.localizedDescription)")
return
}
else{
if let downloadURL = url?.absoluteString {
let idRoom = self.BASE_REF.child("rooms").childByAutoId()
idRoom.setValue(["caption":caption, "thumbnailUrlFromStorage": self.storageRef.child(metadata!.path!).description,"fileUrl": downloadURL])
}
}
})
}
}
I have the same problem, and I found the following solution,
I hope it is useful to someone.
Swift 5
import FirebaseAuth
import FirebaseStorage
import FirebaseFirestore
typealias AddStoryResult = (Bool, Error?) -> Void
typealias UploadImageResult = (StorageMetadata?, Error?) -> Void
class StoryFirebaseAPI {
static let storage = Storage.storage()
static var downloadUrlString: URL?
var image: UIImage?
let photoUri = "smth uri path"
uploadImage(image, photoUriString: photoUri) { (metadata: StorageMetadata?, error: Error?) in
guard let metadata = metadata else {
if let error = error {
print("Error occured: \(error)")
}
completion(false, error)
return
}
// and at this point I have print(downloadUrlString)
completion(true, nil)
}
}
extension StoryFirebaseAPI {
func uploadImage(_ image: UIImage, photoUriString: String, completion: #escaping UploadImageResult) {
guard let imageData = image.jpegData(compressionQuality: 0.5) else {
print("smth error")
completion(nil, nil)
return
}
let storageRef = storage.reference().child(photoUriString)
let imageMetadata = StorageMetadata()
imageMetadata.contentType = "image/jpeg"
storageRef.putData(imageData, metadata: imageMetadata) { (storageMetadata, error) in
if let error = error {
print("Error: \(error.localizedDescription)")
completion(nil, error)
return
}
guard let unwrappedMetadata = storageMetadata else {
print("smth error")
print("Error: \(error?.localizedDescription ?? "")")
completion(nil, error)
return
}
storageRef.downloadURL { url, error in
if let error = error {
print("Error: \(error.localizedDescription)")
completion(nil, error)
return
} else {
if let url = url {
downloadUrlString = url
completion(unwrappedMetadata, nil)
}
}
}
print("Image uploaded successfully")
}
}
}
I have an image that is uploaded to the Firebase Storage but I can not get the downloadURL of this to save it in my database.
I already read a lot of posts on StackOverflow but there was nothing working out for me. The image is loaded into the storage but the error says that it is not existing.
let image = self.selectedImage
let imageData = UIImageJPEGRepresentation(image, 0.1)
let storageRef = Storage.storage().reference().child(uid)
storageRef.putData(imageData, metadata: nil) // i know that i can use a completion here but i left it for now
storageRef.downloadURL { url, error in
if let error = error {
print(error)
} else {
// do sth. else
}
}
These are the errors that I get:
FIRStorageErrorDomain Code=-13010 "Object W002MjRvi0d8JfVwImUJhH0ph2O2 does not exist."UserInfo={object=W002MjRvi0d8JfVwImUJhH0ph2O2,
ResponseBody={
"error": {
"code": 404,
"message": "Not Found. Could not get object"
}
}
ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=404}
Please check Storage Rules
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth!=null;
}
}
}
In Your ViewController
import Firebase
import FirebaseAuth
import ImageIO
var imgData: NSData = NSData(data: UIImageJPEGRepresentation((self.img_Photo?.image)!, 0.5)!)
self.uploadProfileImageToFirebase(data: imgData)
func uploadProfileImageToFirebase(data:NSData){
guard let userID = Auth.auth().currentUser?.uid else {
return
}
let storageRef = Storage.storage().reference().child(“Images”).child(userID)
if data != nil {
storageRef.putData(data as Data, metadata: nil, completion: { (metadata, error) in
if(error != nil){
print(error)
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) ?? ""
}
}
})
}
}
Storage.storage().reference().child(ImageUid).putData(ImageData, metadata: metadata) { (metadata, error) in
if error != nil {
print("Couldn't Upload Image")
} else {
print("Uploaded")
let downloadURl = metadata?.downloadURL()?.absoluteString
if let url = downloadURl {
self.SetUpUser(Image: url)
}
}
}
}
}
Error:
'downloadURL()' is deprecated: Use
StorageReference.downloadURLWithCompletion() to obtain a current
download URL.
How do I fix this?
The error says that you need to use StorageReference.downloadURLWithCompletion() well you need to use it:
let storageItem = Storage.storage().reference().child(ImageUid)
storageItem.putData(ImageData, metadata: metadata) { (metadata, error) in
if error != nil {
print("Couldn't Upload Image")
} else {
print("Uploaded")
storageItem.downloadURL(completion: { (url, error) in
if error != nil {
print(error!)
return
}
if url != nil {
self.SetUpUser(Image: url!.absoluteString)
}
}
}
}
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)
}
}
}
}