Firebase多个观察者复制单元格

时间:2017-08-03 15:28:10

标签: ios swift uitableview 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进行测试。但用户是主要的快速文件。

1 个答案:

答案 0 :(得分:0)

尝试更改

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并在闭包内执行此操作:

让用户拥有一个名为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阵列中的任何用户是否具有相同的用户ID,如果有,则更新匹配userID用户的displayname。如果friendsList中没有用户与userID匹配,则会将用户追加到friendsList的末尾,因为它是一个新用户,但尚未在该数组中使用。