0

My Firebase database looks like thisenter image description here

This is the Rules of database

{
  "rules": {
      ".read": "auth!=true",
      ".write":"auth!=true",
    "users": {
      "$uid": {
        ".indexOn": "lastTxt"
      }
    }
  }
}

Currently there are 11 children in "rjs" nodes. I created a UITableView() to show the "conection", "displayName" & "img_url" of each rj and used this below code to achieve that.

class RJData {

    var name: String?
    var connection: String?
    var url: String?

    init(name: String?, connection: String?, url: String?) {
        self.name = name
        self.connection = connection
        self.url = url
    }
}

 var rjUIDs = [String]()
 var rjInfo = [RJData]()

func fetchInfoForAllRj()
{
    Database.database().reference().child("rjs").observe(.value, with: { (snapshot) in

        print("\n\n\n ----- snapshot = \(snapshot)\n\n\n")

        for child in snapshot.children.allObjects as! [DataSnapshot]
        {
            let rjID = child.key
            self.rjUIDs.append(rjID)

            if let dictionary = child.value as? [String: AnyObject], let name = dictionary["displayName"] as? String, let connection = dictionary["connection"] as? String, let url = dictionary["img_url"] as? String
            {
                let data = RJData(name: name, connection: connection, url: url)
                self.rjInfo.append(data)
            }
        }

        DispatchQueue.main.async {
            self.tableView_RJS.reloadData()
        }

    }, withCancel: nil)
}

I am caching image using this function

extension UIImageView {
public func imageFromURL(urlString: String) {

    let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
    activityIndicator.frame = CGRect.init(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)
    activityIndicator.startAnimating()
    if self.image == nil{
        self.addSubview(activityIndicator)
    }

    URLSession.shared.dataTask(with: NSURL(string: urlString)! as URL, completionHandler: { (data, response, error) -> Void in

        if error != nil {
            print(error ?? "No Error")
            return
        }
        DispatchQueue.main.async(execute: { () -> Void in
            let image = UIImage(data: data!)
            activityIndicator.removeFromSuperview()
            self.image = image
        })

    }).resume()
}

}

It does my job but takes 30 to 50 secs to load the UITableView() for the first time. After that it takes nearly 1 sec to load the UITableView(), I mean it works fine after the first time.

What can I do to reduce the loading time? Any assistance would be appreciated.

pigeon_39
  • 1,503
  • 2
  • 22
  • 34
  • Are you caching some image data from img_url? Could delay be possible because it's caching the img_url's image data for the first time? – Mumtaz Hussain Sep 30 '19 at 11:09
  • If I remember my own work with Firebase correctly, isn't the `.childAdded` observer fired for every child in that path? So you're reloading the tableview 11 times already just through that – henrik-dmg Sep 30 '19 at 11:16
  • Yes, it loads my UITableView 11 times :( Where should I change? @henrik-dmg – pigeon_39 Sep 30 '19 at 11:34
  • I checked & I think this is not because of caching. What would be the probable cause? any idea @MumtazHussain – pigeon_39 Sep 30 '19 at 11:34
  • @pigeon_39 try changing `.childAdded` to `.value` and then access the snapshot's children like this `for child in snapshot.children { ... }` – henrik-dmg Sep 30 '19 at 13:07
  • tried but didn't work :( @henrik-dmg any other idea? – pigeon_39 Sep 30 '19 at 13:31
  • Have you tried not loading the image to debug it? I assume you have some `UIImageView` in a tableview cell and then assign the data to that cell and it's using the url to download the image asynchronously, correct? – henrik-dmg Sep 30 '19 at 14:56
  • I updated my fetchInfoForAllRj() function and changed the image caching function but no result @henrik-dmg – pigeon_39 Oct 01 '19 at 06:57
  • @pigeon_39 have you measured what the block is that actually takes so long? Also check out this answer https://stackoverflow.com/a/37019507/4553482 – henrik-dmg Oct 02 '19 at 07:20
  • You don't need this `DispatchQueue.main.async` inside Firebase closures as UI calls are run on the main thread. Also, `imageFromURL` is not called anywhere in the code in your question so it's unclear how that's being used. Lastly, I ran the code in your `fetchInfoForAllRj` function and it retrieved 1000 objects from Firebase in .82 seconds. – Jay Oct 02 '19 at 19:32

0 Answers0