数据库更改后,Firebase项目在集合视图中多次返回

时间:2019-07-13 07:19:10

标签: swift firebase firebase-realtime-database

在我的应用程序内部调用了用于创建或删除列表的功能时,其余列表将被复制并在collectionView中多次显示,直到重新加载该应用程序为止。我只在fetchLists和上拉刷新功能中两次调用过viewDidLoad函数。一按即可刷新列表,恢复正常。

获取列表:

   fileprivate func fetchLists() {
    self.collectionView?.refreshControl?.endRefreshing()

    guard let currentUid = Auth.auth().currentUser?.uid else { return }

    let ref = Database.database().reference().child("list-feed").child(currentUid)
    ref.observe(.value) { (listFeedSnapshot) in

        guard var allObjects = listFeedSnapshot.children.allObjects as? [DataSnapshot] else { return }

        allObjects.forEach({ (allObjectsSnapshot) in

            let listId = allObjectsSnapshot.key

            let listRef = Database.database().reference().child("lists").child(listId)
            listRef.observeSingleEvent(of: .value, with: { (snapshot) in

                guard let dict = snapshot.value as? [String: Any] else { return }
                guard let uid = dict["uid"] as? String else { return }

                Database.fetchUserWithUID(uid: uid, completion: { (user) in
                    guard let dictionary = snapshot.value as? [String: Any] else { return }

                    var list = List(user: user, dictionary: dictionary)

                    let listId = snapshot.key
                    list.id = snapshot.key
                    self.list = list

                    self.lists.append(list)

                    self.lists.sort(by: { (list1, list2) -> Bool in
                        return list1.creationDate.compare(list2.creationDate) == .orderedDescending
                    })

                    self.collectionView?.reloadData()
                    ref.keepSynced(true)
                    listRef.keepSynced(true)
                })
            })
        })
    }
}

创建列表:

 let values = ["uid": uid, "title": listNameText, "creationDate": Date().timeIntervalSince1970] as [String : Any]
 ref.updateChildValues(values, withCompletionBlock: { (error, ref) in
 if let error = error {
                        self.navigationItem.rightBarButtonItem?.isEnabled = true
 print("failed to save user info into db:", error.localizedDescription)
                        return
                    }

let memberValues = [uid : 1]

ref.child("list-members").updateChildValues(memberValues)

self.handleUpdateFeeds(with: ref.key!)
self.handleListFeeds(with: ref.key!)

print("successfully created list in db")

更新供稿:

    func handleUpdateFeeds(with listId: String) {

    guard let uid = Auth.auth().currentUser?.uid else { return }

    let values = [listId: 1]

    Database.database().reference().child("list-feed").child(uid).updateChildValues(values)
}

func handleListFeeds(with listId: String) {

    guard let uid = Auth.auth().currentUser?.uid else { return }

    let values = [listId: 1]

    Database.database().reference().child("user-lists").child(uid).updateChildValues(values)
}

Firebase数据库:

  {
  "list-feed" : {
  "otxFDz0FNbVPpLN27DYBQVP4e403" : {
  "-LjeAoHJTrYK7xjwcpJ9" : 1,
  "-LjeApq-Mb_d_lAz-ylL" : 1
  }
  },
  "lists" : {
  "-LjeAoHJTrYK7xjwcpJ9" : {
  "creationDate" : 1.5630020966384912E9,
  "title" : "Test 1",
  "uid" : "otxFDz0FNbVPpLN27DYBQVP4e403"
},
"-LjeApq-Mb_d_lAz-ylL" : {
  "creationDate" : 1.563002101329072E9,
  "list-members" : {
    "otxFDz0FNbVPpLN27DYBQVP4e403" : 1
  },
  "title" : "Test 2",
  "uid" : "otxFDz0FNbVPpLN27DYBQVP4e403"
}
}
}

db

1 个答案:

答案 0 :(得分:1)

由于您正在调用ref.observe(,因此将永久性观察者附加到数据上。这意味着,如果您每秒调用fetchLists,则将附加第二个观察者,并且两次将获得相同的数据。

如果您只希望每次调用fetchLists时读取一次数据,则应使用observeSingleEventOfType

fileprivate func fetchLists() {
    self.collectionView?.refreshControl?.endRefreshing()

    guard let currentUid = Auth.auth().currentUser?.uid else { return }

    let ref = Database.database().reference().child("list-feed").child(currentUid)
    ref.observeSingleEvent(of: .value) { (listFeedSnapshot) in

另请参阅reading data once上的文档。