尽管之前已从Firebase提取数据,但有时仍未将其添加到单元中

时间:2019-04-19 03:48:01

标签: ios swift firebase firebase-realtime-database

我通过以下方式从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")

所有这些都将“随机”打印空字符串。有时我应该注意它们确实起作用。我发现始终如一的第一个单元格项目完美地工作,而其他两个单元格则没有。

为什么会发生这种情况以及如何解决?

更新:

以下是一些要求的代码:

    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个项目)中的中间2个项目(始终如此:->索引1和2总是有问题,无论n可能是什么)。更多项目会导致仅项目1和2出现问题)

1 个答案:

答案 0 :(得分:1)

您的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方法中进行了以下更改:

  • 如果快照的值不存在,则不需要两个警卫声明测试
  • 您将常量userUID设置为等于user,因此if语句if user == userUID将始终成功
  • 在循环之前将userObj设置为常量,这样就不会设置每次循环迭代。