【问题标题】:Asynchronous Data in tableView Firebase SwifttableView Firebase Swift 中的异步数据
【发布时间】:2017-07-08 09:10:20
【问题描述】:

我对 Firebase 中我最不喜欢的部分有疑问。我想从用户的以下列表中拉出一个帖子(每个用户只有一个帖子)。首先,我创建了一个完成处理程序以从 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)
    })
}

现在的计划是从 userArray 的每个元素中提取一个帖子。 这是问题开始的地方。我在 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()
    }
}

在我看来一切正常,但肯定不是。以下是我创建单元格的方法:

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
}

控制台中的输出会有所不同,但通常我会得到: 1 1 3 3 2 2

这个想法是首先从 Firebase 检索所有数据,将其添加到 post 对象,将对象附加到数组,然后为该对象创建单元格并下载数据。即使未检索到数据,也已创建单元格。我认为这就是问题所在。谢谢,每一个建议都值得赞赏。

【问题讨论】:

  • observeSingleEvent() 是一种异步方法。您需要将帖子附加到完成块中,这与您现在所做的不同
  • 谢谢仁。如您所见,我想在两个事件完成后附加帖子,因为我有 2 个要从中获取数据的来源。解决方案是在第一个事件中附加它并在第二个事件中“修改”它吗?

标签: ios swift firebase


【解决方案1】:

您需要内部查询以结合用户个人资料数据和发布数据。 像这样-

    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()
                    }
                })
            })
        }
    }

【讨论】:

  • 很高兴它有帮助!快乐编码:)
  • 当我做这样的事情时,数据是按用户分组的(因为调用顺序是这样的)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-05
相关资源
最近更新 更多