首页 > 解决方案 > 尽管之前已获取过从 firebase 获取的数据,但有时不会将其添加到单元格中

问题描述

我通过以下方式从 firebase 获取数据:

fetchUsers (gets UIDs of people the current user follows)
  -for each user fetch his posts
     -for this user fetch his personal user-data (like profile image and username)

注意:我在调用“为每个用户获取他的帖子”后重新加载数据,并在每个帖子的内部重新加载数据。

现在这是奇怪的部分。在下面显示的方法中,当向 firebase 查询必要的数据时会调用该方法,其中有显示数据的打印语句。查看此数据时,它总是根据需要出现(个人资料图片 URL 以及用户名等。)

    func addUserDataToObject(userObj: User, snapshot: DataSnapshot) {
    if (snapshot.childSnapshot(forPath: "username").value as! String) != "" {
        userObj.profileImageUrlString = "\(snapshot.childSnapshot(forPath: "profileImage").value as! String)"
        userObj.fullName = "\(snapshot.childSnapshot(forPath: "fullName").value as! String)"
        userObj.username = "\(snapshot.childSnapshot(forPath: "username").value as! String)"
        print("\(snapshot.childSnapshot(forPath: "profileImage").value as! String)", " this was wireed")
    } else {
        print("the username was nil!")
    }
}

但是,当我尝试在 collectionView 方法中使用该数据时,它不存在:我打印:

                print(postArray[indexPath.item].user.username, " This is supposed to be the username")
            print(postArray[indexPath.item].user.profileImageUrlString!, " This is supposed to be the URL")
            print(date, " This is supposed to be the date")

所有这些都将“随机”打印空字符串。有时我应该注意到它们确实有效。我发现第一个单元格项目始终运行良好,但其他 2 个则没有。

为什么会发生这种情况,我该如何解决?

更新:

这是一些请求的代码:

    func fetchAllUserFirstPostMedia(user: String) {
    print("2344 fetch called 32424243242")

    let databaseN = Database.database().reference()

    databaseN.child("Posts").child(user).observe(.value, with: {(snapshot) in

        guard snapshot.value as? [String: AnyObject] != nil else { return print("\(snapshot.value) <-- this is snapshot.value in return statement") }

        let userUID = user
        if user == userUID {

            guard let postDictionary = snapshot.value as? [String:AnyObject] else { return }

            for anyPosts in postDictionary {
                print("inside the anyPosts")//will print as many times as there are posts.

                let currentPost = Post()

                let userObj = User(theuserID: userUID)
                self.retrieveUsersInfo(userObj: userObj)
                print(userObj.profileImageUrlString, " This is teh uirl for prof image")//this is Always empty (even though at leaased the first value has an image dysplayed and all seem to ahve had one when in the retriveUsersInfo() method)
              ...

更新2:

我发现问题只发生在集合视图(如果它有 4 个项目。更多项目导致仅针对有问题的第 1 项和第 2 项)

标签: iosswiftfirebasefirebase-realtime-database

解决方案


您的retrieveUsersInfo(userObj: User)方法是异步的,因此用于填充的数据collectionView可能没有及时加载。

尝试将您的方法重写retrieveUsersInfo为闭包,然后在找到您的用户信息后遍历帖子字典(我不知道您对anyPosts循环遍历的对象做了什么,但这就是我所拥有的):

func fetchAllUserFirstPostMedia(user: String) {
    print("2344 fetch called 32424243242")

    let ref = Database.database().reference()

    ref.child("Posts/\(user)").observe(.value, with: { snapshot in

        guard let postDictionary = snapshot.value as? [String:AnyObject] else {
            print("\(snapshot.value) <-- this is snapshot.value in return statement")

            return
        }

        let userObj = User(theuserID: user)
        var posts = [Post]()

        self.retrieveUsersInfo(userObj: userObj) {
            print(userObj.profileImageUrlString)

            for anyPosts in postDictionary {
                print("inside the anyPosts")

                let currentPost = Post()

                // do whatever you need to do with anyPosts, currentPost, and userObj

                // add post object to array
                posts.append(currentPost)
            }

            print(posts) // all of your posts with the complete userObj
        }
    })
}

func retrieveUserInfo(userObj: User, completion: @escaping () -> Void) {
    let ref = Database.database().reference()
    // I'm assuming this UID object is the userObj's uid and it's coming from somewhere else?
    ref.child("Users").child(UID).observe(.value, with: { snapshot in
        self.addUserDataToObject(userObj: userObj, snapshot: snapshot)
        completion()
    })
}

fetchAllUserFirstPostMedia我在你的方法中改变了几件事:

  • 如果快照的值退出,您不需要两个保护语句测试
  • 您将常量设置userUIDuser,因此 if 语句if user == userUID将始终成功
  • 在循环之前设置userObj常量,因此它不会设置每个循环迭代。

推荐阅读