简体   繁体   English

tableView Firebase Swift中的异步数据

[英]Asynchronous Data in tableView Firebase Swift

I have an issue with my least favourite part in Firebase. 我在Firebase中最不喜欢的部分出现了问题。 I want to pull a post from user's following list (every user has one and only one post). 我想从用户的关注列表中拉一条帖子(每个用户只有一个,只有一个帖子)。 First, I created a completion handler to get a list of all followers from Firebase and store it in userArray array of strings: 首先,我创建了一个完成处理程序,以从Firebase获取所有关注者的列表,并将其存储在userArray字符串数组中:

func GetUsersInFollowing(completion: @escaping (Bool) -> ()) {
    ref.child("following").queryOrdered(byChild: FIRAuth.auth()!.currentUser!.uid).observeSingleEvent(of: .value, with: { (snapshot) in
        for group in snapshot.children {
            self.userArray.append((group as AnyObject).key)
        }
        completion(true)
    })
}

Now the plan is to pull a post from every element of userArray. 现在的计划是从userArray的每个元素中提取一个帖子。 Here is where the problem starts. 这是问题开始的地方。 I call CreatePosts() immediately after GetUsersInFollowing() completes. 我在GetUsersInFollowing()完成后立即调用CreatePosts()。

func CreatePosts() {
    for x in userArray {
        var thePost = Post()
        print("1")
        self.ref.child("users").child(x).observeSingleEvent(of: .value, with: { (snapshot) in
            let value = snapshot.value as? NSDictionary
            thePost.fullName = value?["fullname"] as? String ?? ""
            thePost.username = value?["username"] as? String ?? ""
            thePost.profileImageURL = value?["photourl"] as? String ?? ""
            print("2")
        })

        self.ref.child("posts").child(x).observeSingleEvent(of: .value, with: { (snapshot) in
            let value = snapshot.value as? NSDictionary
            thePost.description = value?["description"] as? String ?? ""
            thePost.info = value?["location"] as? String ?? ""
            thePost.postImageURL = value?["photoURL"] as? String ?? ""
            thePost.timePost = value?["timestamp"] as? NSDate
            thePost.upVotes = value?["upvotes"] as? Int ?? 0
        })

        self.postArray.append(thePost)
        self.tableView.reloadData()
    }
}

Everything looks ok to me, but it surely isn't. 一切对我来说看起来不错,但肯定不是。 Here's how I create cells: 这是我创建单元格的方法:

func configureCell(post: Post) {
    self.post = post
    self.username.text = post.username
    self.profileImage = post.profileImageURL
    print("3")
    self.fullname.text = post.fullName
    self.timestamp.text = post.timePost
    self.upvotes.text = post.upVotes
    self.location.text = post.location
    self.descriptionText.text = post.description
}

The output in the console varies, but usually I get: 1 1 3 3 2 2 控制台中的输出会有所不同,但通常我会得到:1 1 3 3 2 2

The idea is to first retrieve all data from Firebase, add it to post object, append the object to the array and then create cell for that object with data downloaded. 这个想法是首先从Firebase检索所有数据,将其添加到发布对象,将该对象附加到数组,然后为下载了数据的该对象创建单元。 Cell is already created even though data is not retrieved. 即使未检索到数据,也已经创建了单元。 I think that is the problem. 我认为这就是问题所在。 Thank you, every suggestion is appreciated. 谢谢您,每个建议都值得赞赏。

You need to inner query for combining both user profile data and post data. 您需要内部查询以同时组合用户个人资料数据和帖子数据。 Like this - 像这样 -

    func CreatePosts() {

        //Using userPostArrayObjFetched as a counter to check the number of data fetched.
        //Remove this code, if you don't want to wait till all the user data is fetched.
        var userPostArrayObjFetched = 0

        for (index,userID) in userArray.enumerated() {

            print("1" + userID)

            self.ref.child("users").child(userID).observeSingleEvent(of: .value, with: { (snapshot) in

                var thePost = Post()

                let value = snapshot.value as? NSDictionary
                thePost.fullName = value?["fullname"] as? String ?? ""
                thePost.username = value?["username"] as? String ?? ""
                thePost.profileImageURL = value?["photourl"] as? String ?? ""
                print("2" + userID)

                self.ref.child("posts").child(userID).observeSingleEvent(of: .value, with: { (snapshot) in
                    let value = snapshot.value as? NSDictionary
                    thePost.description = value?["description"] as? String ?? ""
                    thePost.info = value?["location"] as? String ?? ""
                    thePost.postImageURL = value?["photoURL"] as? String ?? ""
                    thePost.timePost = value?["timestamp"] as? NSDate
                    thePost.upVotes = value?["upvotes"] as? Int ?? 0
                    print("3" + userID)

                    self.postArray.append(thePost)

//                      Uncomment if you want to reload data as fetched from Firebase without waiting for all the data to be fetched.
//                    self.tableView.reloadData()

                    userPostArrayObjFetched += 1

                    if userPostArrayObjFetched == userArray.count{
                         self.tableView.reloadData()
                    }
                })
            })
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM