Firebase中的数据更改时,Swift CollectionView.reload数据无法正常工作?

时间:2018-06-19 07:55:50

标签: swift firebase

我目前拥有此工作代码,该代码从Firebase中的users位置读取,其中包含每个用户的所有用户个人资料信息。我正在使用从Firebase返回的快照(数据)构建我的阵列并在CollectionView中显示用户。

我预期(未发生)的行为是,当user属性的值在Firebase中发生更改时(例如; online状态更改为“离线”#);然后应该将其下推到我的应用程序,以便CollectionView更新,因此不会显示刚刚离开的用户"离线"。

我在下面使用正确的Firebase查询吗?

self.REF_USERS.observeSingleEvent(of: .value , with: { (snapshot) in

                    guard let usersSnapshot = snapshot.children.allObjects as? [DataSnapshot] else { return }

                    for user in usersSnapshot{

                        let discoverable = user.childSnapshot(forPath: "discoverable").value as! Bool

                        if user.key == key && discoverable == true {

                            let uid = user.key
                            let name = user.childSnapshot(forPath: "name").value as! String
                            let email = user.childSnapshot(forPath: "email").value as! String
                            let profilePictureURL = user.childSnapshot(forPath: "profilePictureURL").value as! String

                            let birthday = user.childSnapshot(forPath: "birthday").value as! String
                            let firstName = user.childSnapshot(forPath: "firstName").value as! String
                            let lastName = user.childSnapshot(forPath: "lastName").value as! String
                            let gender = user.childSnapshot(forPath: "gender").value as! String
                            let discoverable = user.childSnapshot(forPath: "discoverable").value as! Bool
                            let online = user.childSnapshot(forPath: "online").value as! Bool

                            let discoveryPrefs = user.childSnapshot(forPath: "discoveryPrefs").value as! [String : Any]

                            let dictionary: [String : Any] = ["uid": uid, "name": name, "email": email, "profilePictureURL": profilePictureURL, "birthday": birthday, "firstName": firstName, "lastName": lastName, "gender": gender, "discoverable": discoverable, "online": online, "discoveryPrefs": discoveryPrefs]

                            let user = User(uid: uid, dictionary: dictionary)

                            users.append(user)

                        }//end if

                    }//end for

                    //filter out "remove" current user from array
                    let filteredUsers = users.filter({ (user: User) -> Bool in return !user.uid.contains(uid) })

                    handler(filteredUsers.shuffled(), true)//return a shuffled version of the array via handler

                })//end FIR snapshot call

这就是我使用上面的代码加载/重新加载数据的方法:

DataService.run.getUsersAtVenue(forVenueLocation: location, forUid: userId) { (users, successBool) in

            if successBool {
                self.users = users
                self.collectionView.reloadData()
                Utilities.run.dismissSVHUD(delay: 0.5)

            }
        }

3 个答案:

答案 0 :(得分:0)

您是否处于主线程中,users已更改?试着把它放进去:

         DispatchQueue.main.async {
                if users.count > 0 {
                      self.users = users
                      self.collectionView.reloadData()
                      Utilities.run.dismissSVHUD(delay: 0.5)
                }  
        }

答案 1 :(得分:0)

Roggie,您需要注册一名观察员,以便在特定的“用户”注册时收到通知。节点(用户位置下的孩子)发生变化。此代码应类似于下面的

_refHandleUserChanged = ref.child("users").observe(.childChanged, with: { (snapshot) in
    guard let changedUserIndex = self.userSnapshots.index {$0.key == snapshot.key} else { return }
    self.userSnapshots[changedUserIndex] = snapshot
    self.userCollectionView.reloadRows(at: [IndexPath(row: changedUserIndex, section: 0)], with: .automatic)
})

其中' ref'是对您的Firebase数据库的引用,' _refHandleUserChanged'是当前类的实例var属性(可能是View Controller类)。然后,在取消初始化实例时,应取消注册/删除此观察者,如下面的代码。

deinit {
    ref.child("users").removeObserver(withHandle: _refHandleUserChanged)
}

答案 2 :(得分:0)

在获得所有新数据后,我对小数据集所做的工作是在completionBlock完成之后。

topViewController是CollectionView吗? 如果它被转换为自定义的collectionView 然后调用collectionview.reloadData。

所有这些都嵌入到主队列中。

很有可能在重新获取数据之前重新加载