Rasha
Rasha

Reputation: 1

How to upload a file to Firebase in an iOS app (Swift)

I used this answer https://stackoverflow.com/a/64168754/16212254 for reference to allow the user to pick a file, but now I am stuck on how to upload the file to Firebase. I'm NEW to Swift, please don't mind my silly question.

I tried to follow https://firebase.google.com/docs/firestore/quickstart#ios and https://firebase.google.com/docs/storage/ios/upload-files but still could not figure out how to send the file to firebase since I don't know the attached file's name and path.

Upvotes: 0

Views: 1853

Answers (1)

Nicolò Padovan
Nicolò Padovan

Reputation: 102

The answer you used to be able to pick a file works fine, but doesn't give a reference to the selected image or file outside the scope of the didFinishPickingMediaWithInfo and didPickDocumentsAt functions.

Here's how to save your file/image data to be able to access it later.

  • Create a variable of type Data? in your ViewController.

    var myData: Data?

  • If you are dealing with an Image, inside the didFinishPickingMediaWithInfo function, save the png data of the selected image inside the newly created variable (which scope is not limited to the functions itself). If you are instead dealing with a file, do basically the same thing inside the didPickDocumentAt function.

// Image
if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
    // The following 2 lines don't actually do anything: the selectedImageData dictionary
    // ceases existing as soon as the functions ends
    // selectedImageData["filename"] = fileUrl.lastPathComponent
    // selectedImageData["data"] = pickedImage.pngData()?.base64EncodedString(options: .lineLength64Characters)

    self.myData = pickedImage.pngData()
}

// File
do {
    let fileData = try Data.init(contentsOf: file.absoluteURL)
    // The following 2 lines don't actually do anything: the selectedFileData dictionary
    // ceases existing as soon as the functions ends
    // selectedFileData["filename"] = file.lastPathComponent
    // selectedFileData["data"] = fileData.base64EncodedString(options: .lineLength64Characters)

    self.myData = fileData
} catch {
    // ...
}

Then, to upload the data to the Firebase Storage, you can use the following function:

import FirebaseStorage // At the beginning of the file

// Uploads the selected image/file data there is any.
func uploadSavedData() {
    guard let data = myData else { return } // Checks whether there is actual data to upload.

    let storageRef = Storage.storage().reference()
    let fileRef = storageRef.child("userUID/files/documentName.png")

    let uploadTask = fileRef.putData(data, metadata: nil) { (metadata, error) in 
        guard let metadata = metadata else { return } // Cancels task if there is any error
        
        fileRef.downloadURL { (url, error) in {
            guard let downloadURL = url else { return }
            print(downloadURL) // Prints the URL to the newly uploaded data.
        }
    }
}

Further resources on the topic

Upvotes: 2

Related Questions