Firebase实时阵列计数不匹配

时间:2017-06-06 00:18:49

标签: ios swift firebase firebase-realtime-database

我有一个使用Firebase实时数据库的iOS swift应用程序。如果到目前为止我正常使用该应用程序,我找不到任何问题。但是,我想预测边缘情况。

我在推送更新之前试图强调测试我的应用程序,我正在做的一种方法是快速从带有tableView的VC来回到下一个VC,这是一个详细的VC。如果我多次这样做,最终tableview将显示大量重复数据。

我测试了我的应用程序,在我的模拟器上打开了一个tableview,然后进入我的Firebase控制台并手动更改了一个值,并立即在设备上更改了字符串。

所以我很困惑为什么我的tableview会显示不正确数量的孩子,如果它不断检查该值应该是什么。

// MARK: Firebase Methods

func checkIfDataExits() {
    DispatchQueue.main.async {
        self.cardArray.removeAll()
         self.ref.observe(DataEventType.value, with: { (snapshot) in
            if snapshot.hasChild("cards") {
                self.pullAllUsersCards()
            } else {
                self.tableView.reloadData()
            }
        })
    }
}



func pullAllUsersCards() {
    cardArray.removeAll()
    let userRef = ref.child("users").child((user?.uid)!).child("cards")
    userRef.observe(DataEventType.value, with: { (snapshot) in
        for userscard in snapshot.children {
            let cardID = (userscard as AnyObject).key as String
            let cardRef = self.ref.child("cards").child(cardID)
            cardRef.observe(DataEventType.value, with: { (cardSnapShot) in
                let cardSnap = cardSnapShot as DataSnapshot
                let cardDict = cardSnap.value as! [String: AnyObject]
                let cardNickname = cardDict["nickname"]
                let cardType = cardDict["type"]
                let cardStatus = cardDict["cardStatus"]
                self.cardNicknameToTransfer = cardNickname as! String
                self.cardtypeToTransfer = cardType as! String
                let aCard = CardClass()
                aCard.cardID = cardID
                aCard.nickname = cardNickname as! String
                aCard.type = cardType as! String
                aCard.cStatus = cardStatus as! Bool
                self.cardArray.append(aCard)
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            })
        }
    })
}

1 个答案:

答案 0 :(得分:4)

我得到了帮助并彻底改变了我的代码,所以现在它可以正常工作

func checkIfDataExits() {
    self.ref.observe(DataEventType.value, with: { (snapshot) in
        if snapshot.hasChild("services") {
            self.pullCardData()
        } else {
            DispatchQueue.main.async {
                self.collectionView.reloadData()
            }
        }
    })
}


func pullCardData() {
    let cardRef = self.ref.child("cards")
    cardRef.observe(DataEventType.value, with: { (snapshot) in
        for cards in snapshot.children {
            let allCardIDs = (cards as AnyObject).key as String
            if allCardIDs == self.cardID {
                if let childId = self.cardID {
                    let thisCardLocation = cardRef.child(childId)
                    thisCardLocation.observe(DataEventType.value, with: { (snapshot) in
                        let thisCardDetails = snapshot as DataSnapshot
                        if let cardDict = thisCardDetails.value as? [String: AnyObject] {
                            self.selectedCard?.cardID = thisCardDetails.key
                            self.selectedCard?.nickname = cardDict["nickname"] as? String ?? ""
                            self.selectedCard?.type = cardDict["type"] as? String ?? ""
                            self.pullServicesForCard()
                        }
                    })
                }
            }
        }
    })
}

func pullServicesForCard() {
    if let theId = self.cardID {
        let thisCardServices = self.ref.child("cards").child(theId).child("services")
        thisCardServices.observe(DataEventType.value, with: { (serviceSnap) in
            if self.serviceArray.count != Int(serviceSnap.childrenCount) {
                self.serviceArray.removeAll()
                self.fetchAndAddAllServices(serviceSnap: serviceSnap, index: 0, completion: { (success) in
                    if success {
                        DispatchQueue.main.async {
                            self.collectionView.reloadData()
                        }
                    }
                })
            }
        })
    }
}

func fetchAndAddAllServices(serviceSnap: DataSnapshot, index: Int, completion: @escaping (_ success: Bool) -> Void) {
    if serviceSnap.hasChildren() {
        if index < serviceSnap.children.allObjects.count {
            let serviceChild = serviceSnap.children.allObjects[index]
            let serviceID = (serviceChild as AnyObject).key as String

            let thisServiceLocationInServiceNode = self.ref.child("services").child(serviceID)

            thisServiceLocationInServiceNode.observeSingleEvent(of: DataEventType.value, with: { (thisSnap) in
                let serv = thisSnap as DataSnapshot

                if let serviceDict = serv.value as? [String: AnyObject] {

                    let aService = ServiceClass(serviceDict: serviceDict)
                    self.serviceCurrent = serviceDict["serviceStatus"] as? Bool
                    self.serviceName = serviceDict["serviceName"] as? String ?? ""
                    self.serviceURL = serviceDict["serviceURL"] as? String ?? ""
                    self.serviceFixedBool = serviceDict["serviceFixed"] as? Bool
                    self.serviceFixedAmount = serviceDict["serviceAmount"] as? String ?? ""
                    self.attentionInt = serviceDict["attentionInt"] as? Int

                    self.totalArr.append((serviceDict["serviceAmount"] as? String)!)
                    //                        self.doubleArray = self.totalArr.flatMap{ Double($0) }
                    //                        let arraySum = self.doubleArray.reduce(0, +)
                    //                        self.title = self.selectedCard?.nickname ?? ""

                    //                        if let titleName = self.selectedCard?.nickname {
                    //                            self.title = "\(titleName): \(arraySum)"
                    //                        }

                    aService.serviceID = serviceID
                    if serviceDict["serviceStatus"] as? Bool == true {
                        self.selectedCard?.cStatus = true
                    } else {
                        self.selectedCard?.cStatus = false
                    }



                    if !self.serviceArray.contains(where: { (service) -> Bool in
                        return service.serviceID == aService.serviceID
                    }) {
                        self.serviceArray.append(aService)

                        self.serviceArray.sort {$1.serviceAttention < $0.serviceAttention}

                    }
                }
                self.fetchAndAddAllServices(serviceSnap: serviceSnap, index: index + 1, completion: completion)
            })

        }
        else {
            completion(true)
        }
    }
    else {
        completion(false)
    }

}