Learn Courses My Dashboard

Create a Cloud Storage reference on Apple platforms

Hello,

I have been trying my darndest to try to understand how to display an image that is stored in firebase. I am wanting just the basic knowledge, with just simple code that works that I can run with. There are tutorials out there that do more than just display an image data from Firebase Storage and I find it distracting. All I want is one image displaying in one scene from firebase and I can expand on that.

I’ve been studying this, and I feel like I’m almost getting it but I keep getting errors like, I can’t use a UIImage with a string…The is from Firebase Docs. Please help:

https://firebase.google.com/docs/storage/ios/create-reference#swift_5

// Points to the root reference
let storageRef = Storage.storage().reference()

// Points to "images"
let imagesRef = storageRef.child("images")

// Points to "images/space.jpg"
// Note that you can use variables to create child values
let fileName = "space.jpg"
let spaceRef = imagesRef.child(fileName)

// File path is "images/space.jpg"
let path = spaceRef.fullPath

// File name is "space.jpg"
let name = spaceRef.name

// Points to "images"
let images = spaceRef.parent()
1 Like

@coder3000

Hi Gilbert,

This is the way I have learned how to save images to Storage and save a reference to that image in a collection in Firestore. I hope this code example helps.

        // Create storage reference
        let storageRef = Storage.storage().reference()

        // Using an image from the Assets folder for the purposes of the exercise
        let image = UIImage(named: "TajMahal1")

        // Turn our image into data
        let imageData = image!.jpegData(compressionQuality: 0.8)

        // Check that we were able to convert it to data
        guard imageData != nil else { return }

        // Specify the file path and name
        // NOTE: this example gives the image a UUID() which is always unique.
        let path = "images/\(UUID().uuidString).jpg"
        let fileRef = storageRef.child(path)

        fileRef.putData(imageData!, metadata: nil) { metadata, error in

            //  Check for errors
            if error == nil && metadata != nil {
                //  Get the url for the image in storage
                fileRef.downloadURL { url, error in
                    //  Check for errors
                    if url != nil && error == nil {
                        // Get reference to the database
                        let db = Firestore.firestore()

                        //  Add photos collection document
                        let photos = db.collection("photos")
                        photos.addDocument(data: ["imageurl": url!.absoluteString,
                                                  "name": "TajMahal1",
                                                  "description": "Photograph of Taj Mahal Number 1",
                                                  "date": Date()])
                    }
                }
            }
        }

@coder3000

Hi Gilbert,

Following on from the last sample code where I saved the image, here is a sample where I retrieved the same image.

    func retrieveImage() {

        // Get reference to the database
        let db = Firestore.firestore()

        // Set the collection from where the image is to be sourced
        let photos = db.collection("photos")

        //  Identify the correct record
        let query = photos
            .whereField("name", in: ["TajMahal1"])

        // Execute the query
        query.getDocuments { (querySnapshot, error) in

            // Check for errors
            if let error = error {
                print(error.localizedDescription)
            } else {

                //  Unwrap to ensure that we have a snapshot to deal with
                if let querySnapshot = querySnapshot {

                    // Loop through the documents
                    for doc in querySnapshot.documents {

                        // Extract the path
                        let path = doc["imageurl"] as! String

                        //  Convert that to a URL
                        let url = URL(string: path)

                        // Since we are on a background thread, we must assign the data on the main thread
                        DispatchQueue.main.async {

                            // Assign the image data to where you want to use it
                            model.imageData = try! Data(contentsOf: url!)
                        }
                    }
                }
            }
        }
    }
1 Like

You mean in a different view controller? Not different scene?

You can fetch the data again, or pass it to the other view controller using closures or protocol / delegates

I had a Eureka moment! Here the code that does exactly what I needed. Thought I’d share incase anybody else needs it. Just have an imageView then put the function in viewDidLoad:

private func downloadimages() {
    let reference = Storage.storage().reference(withPath: "\("images/"+Auth.auth().currentUser!.uid+"+.jpg")")
    reference.downloadURL { (URL, error) in
        let data = NSData(contentsOf: URL!)
        let image = UIImage(data: data! as Data)
        self.profileimage.image = image
    }
}

@coder3000

Is this App intended to cater for multiple users?

By the way, just looking at that code and you should be able to use Data(contentsOf: ...) which removes the need to cast as Data in the next statement ie:

private func downloadimages() {
    let reference = Storage.storage().reference(withPath: "\("images/"+Auth.auth().currentUser!.uid+"+.jpg")")
    reference.downloadURL { (URL, error) in
        let data = Data(contentsOf: URL!)
        let image = UIImage(data: data!)
        self.profileimage.image = image
    }
}
1 Like

Yes. Multiple users. Thanks!