Firebase多个观察者复制单元格

我想在tableView中显示当前的用户朋友,但我无法让它完美地工作,当列表中的某个人改变他的名字时,单元格会重复。

JSON:

{ "users" : { "friends_requests" : { "EeLIxkOEfhMUlsM8WGnHdgeT8xW2" : { "friends" : { "WWOdh96Yr3Qs4N3GWDVq3OlQFfB2" : true } }, "WWOdh96Yr3Qs4N3GWDVq3OlQFfB2" : { "friends" : { "EeLIxkOEfhMUlsM8WGnHdgeT8xW2" : true } } }, "profile" : { "EeLIxkOEfhMUlsM8WGnHdgeT8xW2" : { "birthday" : "02/08/2017", "displayname" : "user2", "email" : "11@1.1", "gender" : "M" }, "WWOdh96Yr3Qs4N3GWDVq3OlQFfB2" : { "birthday" : "02/08/2017", "displayname" : "user1", "email" : "112@2.1", "gender" : "M" } } } } 

这是代码:

 var friendList = [Userr]() func addFriendObserver(_ update: @escaping () -> Void) { CURRENT_USER_FRIENDS_REF.observe(.value, with: { (snapshot) in self.friendList.removeAll() let enumerator = snapshot.children while let rest = enumerator.nextObject() as? FIRDataSnapshot { self.ref.child("users").child("profile").child(rest.key).observe(.value, with: { (snapshot) in guard let dictionary = snapshot.value as? [String: Any] else { return } let user = Userr() user.displayname = dictionary["displayname"] as? String self.friendList.append(user) DispatchQueue.main.async { self.tableview.reloadData() } }, withCancel: nil) 

我已经尝试了很多方法并多次问这个问题,但仍然无法让它工作,没有答案。

请有人帮我解决这个问题。

编辑:我使用的新观察者:

  func showUsersObserver(_ update: @escaping () -> Void) { CURRENT_USER_FRIENDS_REF.observe(.value, with: { (snapshot) in self.friendList.removeAll() let keys = snapshot.children while let rest = keys.nextObject() as? FIRDataSnapshot { self.getUser(rest.key, completion: { (user) in self.friendList.append(user) print(self.friendList.count) // This increase each time when user changing his name! or any changes hits his profile. DispatchQueue.main.async { self.tableview.reloadData() } update() }) } // If there are no children, run completion here instead if snapshot.childrenCount == 0 { update() } }) } 

这是为了获取他们的个人资料数据:

 func getUser(_ userID: String, completion: @escaping (User) -> Void) { USER_REF.child(userID).observe(.value, with: { (snapshot) in guard let dictionary = snapshot.value as? [String: Any] else { return } let id = dictionary["uid"] as? String let email = dictionary["email"] as? String let DisplayName = dictionary["displayname"] as? String completion(User(userEmail: email!, userID: id!, userDisplayName: DisplayName!)) }) } 

和朋友列表:

 class User { var uid: String! var displayname: String! var email: String! init(userEmail: String, userID: String, userDisplayName: String) { self.email = userEmail self.uid = userID self.displayname = userDisplayName } } 

我正在使用Userr进行测试。 但用户是主要的swift文件。

尝试改变

 self.ref.child("users").child("profile").child(rest.key).observe(.value, with: { (snapshot) in ... }) 

 self.ref.child("users").child("profile").child(rest.key).observeSingleEvent(of: .value, with: { (snapshot) in ... }) 

.observe会导致…中的代码每次更改参考路径中的数据时运行。 因此,每次更改参考路径中的数据时,都会附加到friendList.observeSingleEvent确保代码只执行一次。

如果您希望在用户数据更改时更新单元格,请继续使用.observe并在闭包内执行此操作:

Make User为用户的按键设置了一个名为uid的属性

 guard let dictionary = snapshot.value as? [String: Any] else { return } let userID = snapshot.key if let friend = self.friendsList.first(where: {$0.uid == userID}) { friend.displayname = dictionary["displayname"] as? String friend.email = dictionary["email"] as? String friend.uid = dictionary["uid"] as? String //update any other properties of the User class completion(friend) } else { let id = dictionary["uid"] as? String let email = dictionary["email"] as? String let displayName = dictionary["displayname"] as? String //update other properties of the User class let user = User(userEmail:email, userID:id, userDisplayName:displayName) self.friendsList.append(user) completion(user) } 

该代码将使得任何时候用户的配置文件更改,它将检查friendsList数组中的任何用户friendsList具有相同的userID,如果是,则更新匹配的userID用户的displayname。 如果在friendsList中没有用户匹配userID,它会将用户追加到friendsList的末尾,因为它是一个尚未在数组中的新用户。