title: How to use reload item at instead of reloading all the data with firestore
body: <p>I have a chat app use Firestore, when a new <code>document or -&gt; (message)</code>, added to the Firestore my collectionView reload all the data over again and the app freezes for a second until all the data reload, I don't know much about collectionViews but I think if am not wrong this happens because of the collectionView trying to calculate the size for each cell this is the debugger message</p>
  <pre><code>The relevant UICollectionViewFlowLayout instance is &lt;UICollectionViewFlowLayout: 0x7fbd974b3c40&gt;, and it is attached to &lt;UICollectionView: 0x7fbd97930600; frame = (0 61; 414 663); clipsToBounds = YES; gestureRecognizers = &lt;NSArray: 0x600002c5df20&gt;; layer = &lt;CALayer: 0x6000023f9640&gt;; contentOffset: {-5, -5}; contentSize: {404, 8}; adjustedContentInset: {5, 5, 5, 5}; layout: &lt;UICollectionViewFlowLayout: 0x7fbd974b3c40&gt;; dataSource: &lt;DELEVARE___ÿØŸäŸÑŸäŸÅÿ±Ÿä.DriverChat: 0x7fbd97843600&gt;&gt;.
  2021-01-16 13:54:43.232052+0200 DELEVARE - ديليفري[51104:999159] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
  </code></pre>
  <p><code>symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.</code></p>
  <p>this debugger message gets called <code>repeated</code> with every cell loaded to collectionView, Here is my collectionView <a href="https://stackoverflow.com/questions/65751634/how-to-solve-uicollectionviewflowlayoutbreakforinvalidsizes">How to solve UICollectionViewFlowLayoutBreakForInvalidSizes</a></p>
  <p>I don't know how to insert only the new appended item to the array in collectionView, I want this just to react like a normal chat app.</p>
  <p>I have tried this</p>
  <pre><code>func getMessages(){
          guard let uid = Auth.auth().currentUser?.uid else {return}
          
          let firestore = Firestore.firestore()
          let doc = firestore.collection(&quot;طلبات قيد العمل&quot;).whereField(&quot;driverUid&quot;, isEqualTo: uid)
          doc.getDocuments { (query, err) in
              if err != nil {
                  print(err?.localizedDescription ?? &quot;&quot;)
              }
              for document in query!.documents{
  
                  let chatDoc = document.reference.collection(&quot;المحادثات&quot;)
  
                  chatDoc.addSnapshotListener { (querysnap, err) in
                      if err != nil {
                          print(err?.localizedDescription ?? &quot;&quot;)
                      }
                      self.messages = []
                      for snap in querysnap!.documents{
                      
                      let data = snap.data()
                      guard let message = data[&quot;message&quot;] as? String else {return}
                      guard let senderid = data[&quot;senderID&quot;] as? String else {return}
                      guard let timestamp = data[&quot;date&quot;] as? Timestamp else {return}
                      let date = Date(timeIntervalSince1970: TimeInterval(timestamp.seconds))
                      if senderid == Auth.auth().currentUser?.uid{
                          let drivermessages = driverMessages(image: UIImage(), text: message, date: date, isSender: true, driverid: senderid)
  
                          // this line of code is doing the same as collectionView.reloadData()
  
                          self.collectionView?.performBatchUpdates({
                              let indexPath = IndexPath(row: self.comments.count, section: 0)
                              self.messages.append(drivermessages)
                              self.collectionView?.insertItems(at: [indexPath])
                          }, completion: nil)
                          
                      }else {
                          
                          guard let message2 = data[&quot;message&quot;] as? String else {return}
                          guard let senderid2 = data[&quot;senderID&quot;] as? String else {return}
                          guard let timestamp2 = data[&quot;date&quot;] as? Timestamp else {return}
                          guard let img = self.profileImg else {return}
                          let date2 = Date(timeIntervalSince1970: TimeInterval(timestamp2.seconds))
                          
                          let usermessages = driverMessages(image: img, text: message2, date: date2, isSender: false, driverid: senderid2)
                          self.messages.append(usermessages)
                          
                          self.collectionView?.performBatchUpdates({
                              let indexPath = IndexPath(row: self.comments.count, section: 0)
                              self.messages.append(usermessages)
                              self.collectionView?.insertItems(at: [indexPath])
                          }, completion: nil)
                          
                          }
                              
                       }
                   }
                  
               }
           }
        }
  </code></pre>
  <p><em><strong>this is my code</strong></em></p>
  <pre><code>func getMessages(){
          guard let uid = Auth.auth().currentUser?.uid else {return}
  
          
          let firestore = Firestore.firestore()
          let doc = firestore.collection(&quot;طلبات قيد العمل&quot;).whereField(&quot;driverUid&quot;, isEqualTo: uid)
          doc.getDocuments { (query, err) in
              if err != nil {
                  print(err?.localizedDescription ?? &quot;&quot;)
              }
              for document in query!.documents{
                  let chatDoc = document.reference.collection(&quot;المحادثات&quot;)
  
                  chatDoc.addSnapshotListener { (querysnap, err) in
                      if err != nil {
                          print(err?.localizedDescription ?? &quot;&quot;)
                      }
                      self.messages = []
                      for snap in querysnap!.documents{
                      
                      let data = snap.data()
                      guard let message = data[&quot;message&quot;] as? String else {return}
                      guard let senderid = data[&quot;senderID&quot;] as? String else {return}
                      guard let timestamp = data[&quot;date&quot;] as? Timestamp else {return}
                      let date = Date(timeIntervalSince1970: TimeInterval(timestamp.seconds))
                      if senderid == Auth.auth().currentUser?.uid{
                          let drivermessages = driverMessages(image: UIImage(), text: message, date: date, isSender: true, driverid: senderid)
                          self.messages.append(drivermessages)
                          
                      }else {
                          
                          guard let message2 = data[&quot;message&quot;] as? String else {return}
                          guard let senderid2 = data[&quot;senderID&quot;] as? String else {return}
                          guard let timestamp2 = data[&quot;date&quot;] as? Timestamp else {return}
                          guard let img = self.profileImg else {return}
                          let date2 = Date(timeIntervalSince1970: TimeInterval(timestamp2.seconds))
                          
                          let usermessages = driverMessages(image: img, text: message2, date: date2, isSender: false, driverid: senderid2)
                          self.messages.append(usermessages)
                          
                          }
                          DispatchQueue.main.async {
                              self.collectionView.reloadData()
                              let item = self.messages.count - 1
                              let insertionIndexPath = IndexPath(item: item, section: 0)
                              self.collectionView.scrollToItem(at: insertionIndexPath, at: .bottom, animated: true)
                          }
                              
                       }
                   }
                  
               }
           }
        }
  </code></pre>