2017-10-08 4 views
0

ユーザーがチケットを購入して販売できるアプリを作っています。ユーザーは新しいチケットを作成することができ、正常にfirebaseにアップロードすることができますが、チケットIDへの参照は、チケットデータ内のチケットIDを参照するユーザーデータに格納されます。データベースの構造は以下である:Firebaseからデータを解析するときにUITableView要素を正常にリロードできない

DATABASE

  • USERS
  • チケット

チケット

  • TICKET INFO

USER

  • USER INFOチケットのチケットID彼らは私の問題は、私は販売のチケットからチケットをロードする最初の時間は結構ですということです

を販売しています。しかし、ユーザーが販売している新しいチケットを追加すると、テーブルビューはすべてを2回ロードします。

override func viewWillAppear(_ animated: Bool) { 
    self.tickets = [] 
    DataService.ds.REF_USER_CURRENT.child("selling").observe(.value, with: { (snapshot) in //HERE WE REFERNCE OUR SINGELTON CLASS AND OBSERVE CHAMGE TO THE POSTS OBJECT 
     self.tickets = [] //WE CLEAR THE POSTS ARRAY BEFORE WE START MANIPULATION TO MAKE SURE THAT WE DONT REPEAT CELLS 
     if let snapshot = snapshot.children.allObjects as? [DataSnapshot]{ 
      print("ADAM: \(snapshot)")//CHECKING THAT THE OBJECTS EXIST AS AN ARRAY OF DATA SNAPSHOTS 
      for snap in snapshot { 
       DataService.ds.REF_TICKETS.child(snap.key).observe(.value, with: { (snapshot) in 

        if let ticketDict = snapshot.value as? Dictionary<String, AnyObject>{ 

         let ticket = Ticket(ticketID: snap.key, ticketData: ticketDict) 

         self.self.tickets.append(ticket) 
        } 

        self.sell_ticketsTableView.reloadData() 
       }) 
      } 

     } 
     //self.sell_ticketsTableView.reloadData() 
     self.tickets = []//RELAOD THE DATA 
    }) 
} 

どこが間違っているのかはわかりません。

+0

私はあなたがしていることを本当に理解していません。このコードは何ですか? "self.self.tickets.append(ticket) "またはこの "self.tickets = []" ??何をすべきかは、データを解析する前にデータソース配列を空にして、同じチケットが何度も現れないようにすることです。 – Siyavash

+0

@Siyavash the self.tickets = []は、データソースとしてデータソース配列をクリアしようとしていますチケットの配列 – KONADO

+0

私の答えを見てください – Siyavash

答えて

0

コードをこれに変更してください。私はあなたがあなたのユーザーは、彼らがこのリストに何かを追加するたびに意味し、販売しているものの値を観察している

override func viewWillAppear(_ animated: Bool) { 
     self.removeAll() // This is how you clear your array 
     DataService.ds.REF_USER_CURRENT.child("selling").observe(.value, with: { (snapshot) in //HERE WE REFERNCE OUR SINGELTON CLASS AND OBSERVE CHAMGE TO THE POSTS OBJECT 
      self.tickets = [] //WE CLEAR THE POSTS ARRAY BEFORE WE START MANIPULATION TO MAKE SURE THAT WE DONT REPEAT CELLS 
      if let snapshot = snapshot.children.allObjects as? [DataSnapshot]{ 
       print("ADAM: \(snapshot)")//CHECKING THAT THE OBJECTS EXIST AS AN ARRAY OF DATA SNAPSHOTS 
       for snap in snapshot { 
        DataService.ds.REF_TICKETS.child(snap.key).observe(.value, with: { (snapshot) in 

         if let ticketDict = snapshot.value as? Dictionary<String, AnyObject>{ 

          let ticket = Ticket(ticketID: snap.key, ticketData: ticketDict) 

          self.tickets.append(ticket) 
         } 

         self.sell_ticketsTableView.reloadData() 
        }) 
       } 

      } 
      //self.sell_ticketsTableView.reloadData() 
     }) 
    } 
0

あなたの配列をクリアパーツを追加した、あなたのリスナーがトリガーとあなたに新しい価値を提供します全体がusers/$uid/sellingである。

これは、ユーザーが別のチケットを追加したときに2倍に見える理由です。リスナーがトリガーされ、各チケットが配列に再度追加されます。これを回避するには、チケットが追加される前に配列にすでに入っているかどうかをチェックしてください。しかし、現在の実装を改善することができます。

observe(.valueの代わりに.childAddedを使用してください。リスナーは、新しい子が追加されるたびにトリガーされ、その特定の子スナップショットのみを提供します。

リスナーは、最初にその参照で各子に対してトリガーし、それらを個別に配列に追加できます。ただし、すべての子がロードされると、次に追加される子がこのリスナーをトリガーし、配列に追加できます。

+0

ので、私はスナップショットを言うときに、2回目は、それは新しく追加された子を返すだけですか? – KONADO

+0

'.childAdded'を使うと、すべてではなく、一度に1つの子しか返されません。これは、ユーザーが別のチケットを追加することを決定した場合、既にテーブルにある他のすべてのチケットを必要としないので、より良い方法です。また、別の子が追加されたときに子の初期ロード後にトリガーされます。 – Callam

関連する問題