2017-06-06 21 views
5

Mam aplikację z iOS szybką przy użyciu bazy danych czasu rzeczywistego Firebase. Jeśli normalnie używam aplikacji, nie mogę znaleźć żadnego problemu. Jednak chcę przewidywać przypadki skrajne.Niezgodność liczby kart Firebase w czasie rzeczywistym

Próbuję przetestować moją aplikację przed wypychaniem aktualizacji, a jednym ze sposobów, w jaki to robię, jest szybkie przechodzenie wstecz iz powrotem z VC z tableView do następnego VC, który jest szczegółowym VC. Jeśli zrobię to kilka razy, w końcu widok tabeli pokaże mnóstwo duplikatów danych.

Przetestowałem swoją aplikację, otwierając widok tabeli na moim symulatorze i przechodząc do mojej konsoli Firebase i ręcznie zmieniając wartość i natychmiast na urządzeniu zmieniającym się ciąg.

Jestem więc zdezorientowany, dlaczego mój widok tabeli będzie pokazywał niepoprawną liczbę dzieci, jeśli ciągle sprawdza, jaka powinna być wartość.

// 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() 
       } 
      }) 
     } 
    }) 
} 
+0

Czy muszę użyć Firebase metodę na numberOfItemsInSection czy coś? – RubberDucky4444

+0

Nie jesteśmy pewni, czy widzimy wystarczająco dużo kodu. Rzeczy takie jak viewDid/WillAppear będą pomocne, podobnie jak metody tabel i wszelkie właściwości ustawiającego/pobierającego w tablicy zawierającej dane tabeli. Zwykle, gdy występują problemy z duplikatem danych w tabeli, dzieje się tak, ponieważ tablica danych tabeli nie jest czyszczona przed ponownym załadowaniem. Podczas przechodzenia między dwoma różnymi widokami, wszystko w viewWillAppear, na przykład, będzie wywoływane za każdym razem, gdy przełączysz się z powrotem do widoku tabeli. – C6Silver

Odpowiedz

4

mam pomoc i zmieniłem kod drastycznie, więc teraz to działa

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) 
    } 

} 
+0

Wygląda dobrze, polecam tutaj stosowanie niektórych instrukcji strażników. Zwykle coś, co robię, gdy mam dużo if-elses (w ten sposób im wizualnie, pomaga grać z unwrapped vars imo). – murphguy

+0

@murphguy tak, mam wiele rzeczy, których potrzebuję, aby być lepszymi w ... straż to jeden z nich – RubberDucky4444