How can this swift, firebase image fetching, function be made more concise? I am trying to fetch a group of images within a place in Firebase database ref. I then loop through each image adding it to an array which is then supposed to be added to a tableview cell. I was wondering if it could be more concise? am i doing anything unnecessary?

    func fetchAllUserFristImage() {
    Database.database().reference().child(“Posts”).observe(.childAdded, with: {(snapshot) in
        if snapshot.value as? [String: AnyObject] != nil {
            let user = snapshot.key
            self.databaseRef = Database.database().reference()
            let usersPostRef2 = self.databaseRef.child(“Posts”).child(user)
            usersPostRef2.observe(.value, with: {(postXSnapshots) in
                if let postDictionary2 = postXSnapshots.value as? [String:AnyObject] {
                    for (p) in postDictionary2 {
                        if let posts = p.value as? [String:AnyObject] {
                            //to get back to where i was delete the below for i
                            for (i) in posts {

                                if let imageUrlString = i.value as? [String:AnyObject], let postUrl = imageUrlString[“image1”] as? String {
                                    self.feedArray.append(Post(fetchedImageURL: postUrl))
                                    let imageUrl = URL(string: “\(postUrl)“)
                                    do {
                                        print(try Data(contentsOf: imageUrl!))
                                    } catch {
                                        print(error)
                                    }
                                    if let imageDataL = try? Data(contentsOf: imageUrl!) {
                                        let image = UIImage(data: imageDataL)
                                        self.tableData.append(UserImage(image: image!, postNum: p.key, userID: user))
                                        self.tableView.reloadData()
                                    } else {print(“users had no posts, was nil”)}
                                }
                            }
                        }
                    }
                }
            })
            //below shud stay same
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
    })
}


Edit: Posibly I could do somthing wit this postsSnap.childSnapshot(forPath: "ImageUrl").childSnapshot(forPath: "image1") to make it more consise
Thanks!
I would start by investigating the cases where you are performing if lets and basic unwrapping. Cases like if snapshot.value as? [String: AnyObject] != nil can be turned into guard statements and provide routes for early termination. This reduces the pyramid by one level for each early termination.

After that, I see some redundant code in the try section on the innermost level that can be brought together.

Other minor changes I'd make would be regarding variable names, some of the names are not entirely that descriptive and make for some less than ideal reading. More descriptive names with less abbreviation would help understand the code better. Things like usersPostRef2 don't make a lot of sense since we don't see a usersPostRef.

Also lastly, make sure you update the UI on main threads, which you appear to be doing at the end, but not necessarily within the second snapshot closure.

This would give us the following:

func fetchAllUserFristImage() {
    Database.database().reference().child(“Posts”).observe(.childAdded, with: {(snapshot) in
        guard snapshot.value as? [String: AnyObject] != nil else {
            return
        }

        let user = snapshot.key
        self.databaseReference = Database.database().reference()
        let usersPostReference = self.databaseRef.child(“Posts”).child(user)
        usersPostReference.observe(.value, with: {(postXSnapshots) in
            guard let postDictionary = postXSnapshots.value as? [String:AnyObject] else {
                return
            }

            for anyPosts in postDictionary {
                guard let posts = anyPosts.value as? [String:AnyObject] else {
                    return
                }

                //to get back to where i was delete the below for i
                for anyImage in posts {
                    guard let imageUrlString = anyImage.value as? [String:AnyObject], let postUrl = imageUrlString[“image1”] as? String else {
                        return
                    }

                    self.feedArray.append(Post(fetchedImageURL: postUrl))
                    let imageUrl = URL(string: “\(postUrl)“)
                    do {
                        let imageData = try Data(contentsOf: imageUrl!))
                        let image = UIImage(data: imageData)
                        self.tableData.append(UserImage(image: image!, postNum: p.key, userID: user))
                        DispatchQueue.main.async {
                            self.tableView.reloadData()
                        }
                    } catch {
                        print(error)
                    }
                }
            }
        })
        //below shud stay same
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    })
}