1

I have not found any good examples/code for fetching an image from firebase storage/database and displaying it in cells in a basic table view. I looked here as but found nothing that worked. Can someone give a full example?

Bellow is code I have tried to make it work:

import UIKit
import FirebaseStorage
import FirebaseDatabase
import FirebaseAuth
import Firebase

class TableViewController: UITableViewController {

        //TableView datasource methods

        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
            self.downloadImages(cell: cell, folderPath: "\(Storage.storage().reference().child((Auth.auth().currentUser?.uid)!).child("post\(takePicViewController().finalPost + PhotoArray.sharedInstance.numberPost)").child(ImageUploadManager().imageName))", success: { (img) in
                print(img)
            }) { (error) in
                print(error)
            }

//            cell.imageView?.image = PhotoArray.sharedInstance.photosArray[indexPath.row] as? UIImage
            return cell
        }

        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            let numberOfRowsInSection = PhotoArray.sharedInstance.photosArray
            return numberOfRowsInSection.count 
        }

    func downloadImages(cell: UITableViewCell, folderPath:String,success:@escaping (_ image:UIImage)->(),failure:@escaping (_ error:Error)->()){
        for i in 0 ..< 194{
            // Create a reference with an initial file path and name
            let reference = Storage.storage().reference().child((Auth.auth().currentUser?.uid)!).child("post\(takePicViewController().finalPost + PhotoArray.sharedInstance.numberPost)").child(ImageUploadManager().imageName)
            reference.getData(maxSize: (1 * 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)
                    }
                }
//                let cell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
                cell.imageView?.image = UIImage(data: data!)
            }

        }
    }

}

I have also tried the bellow code:

At the beggining of the VC I do the following:

    // Firebase services
var database: Database!
var storage: Storage!

// Initialize Database, Auth, Storage
override func viewDidLoad() {
    database = Database.database()
    storage = Storage.storage()
}

Then I call the function inside the tableView_cellforRowAt indexPath function as seen bellow. And I return cell

       let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
       loadArrayOfImages(cell: cell)

       return cell

The function I called looks like this:

    func loadArrayOfImages(cell: UITableViewCell) {

    let dbRef = database.reference().child((Auth.auth().currentUser?.uid)!).child("post\(takePicViewController().finalPost + PhotoArray.sharedInstance.numberPost)").child(ImageUploadManager().imageName)
    dbRef.observe(.childAdded, with: { (snapshot) in
        // Get download URL from snapshot
        let downloadURL = snapshot.value as! String
        // Create a storage reference from the URL
        let storageRef = self.storage.reference(forURL: downloadURL)
        // Download the data, assuming a max size of 1MB (you can change this as necessary)
        storageRef.getData(maxSize: 10 * 1024 * 1024) { (data, error) -> Void in
            // Create a UIImage, add it to the array
            let pic = UIImage(data: data!)
            self.picArray.append(pic!)
            cell.imageView?.image = pic
        }
    })

   }
}

I do not seem to get any errors and the app does not crash however when I press a button to take me to the TV it is just blanc.

  • You don't need to download the image you can use [SDWebImage](https://github.com/rs/SDWebImage) and pass the imageUrl directly. – TheTiger Aug 28 '18 at 09:47
  • Why web image? this is ios app and we are usinng images created by user –  Aug 28 '18 at 13:31
  • If you checked the above library this is for iOS application. It does asynchronously download the image for a specific `UIImageView`. Don't misunderstand by its name. :) – TheTiger Aug 29 '18 at 04:31
  • @AlexanderTheGreat **Use this for load image** https://stackoverflow.com/a/51746300/10150796 – Nikunj Kumbhani Aug 29 '18 at 06:24

1 Answers1

0

It could be something as simple as reloading your tableView. Remember that your data request to the Firebase servers will not return instantaneously as it is a network call, and as such it could be that your table has 'set' itself before the data has come back. To remedy this, you should use tableView.reloadData(). You could put this at the end of your loadArrayOfImages() function like so:

...
cell.imageView?.image = pic
tableView.reloadData()
pho_pho
  • 672
  • 11
  • 30