title: Swift Firestore: Getting all data from firestore and inputing data into Table View
body: <p><strong>The goal here is to retrieve all the documents of a Firestore Database, then putting the data of those retrieved documents into a Table View.</strong> I'm using Xcode and Firebase.</p>
  
  <p>For example, if I had a Firestore database with this data and documents:</p>
  
  <blockquote>
    <p>Document 1</p>
    
    <blockquote>
      <p>Name: Bob</p>
      
      <p>Email: bob@gmail.com</p>
      
      <p>Phone: 408-111-1234</p>
    </blockquote>
    
    <p>Document 2</p>
    
    <blockquote>
      <p>Name: Joe</p>
      
      <p>Email: joe@yahoo.com</p>
      
      <p>Phone: 408-338-4321</p>
    </blockquote>
  </blockquote>
  
  <p>I would like to have  it all in a table view, maybe something like this:</p>
  
  <blockquote>
    <p>Bob - bob@gmail.com - 408-111-1234</p>
    
    <p>Joe - joe@yahoo.com - 408-338-4321</p>
  </blockquote>
  
  <p>So far, I have this set up: </p>
  
  <p>TableViewController:</p>
  
  <pre><code>class PeopleViewController: UITableViewController {
  
  @IBOutlet var table: UITableView!
  
  var peopleArray = [] as [Array&lt;Any&gt;]
  private var document: [DocumentSnapshot] = []
  
  override func viewDidLoad() {
      super.viewDidLoad()
      table.tableFooterView = UIView(frame: CGRect.zero)
      self.table.delegate = self
      self.table.dataSource = self
  
      loadData()
  
  }
  </code></pre>
  
  <p>And the loadData() func:</p>
  
  <pre><code>func loadData() {
          FirebaseFirestore.root.collection("users").getDocuments { (snapshot, error) in
              if let error = error {
                  print(error.localizedDescription)
              } else {
                  if let snapshot = snapshot {
  
                      for document in snapshot.documents {
  
                          let data = document.data()
                          let name = data["name"] as? String ?? ""
                          let email = data["email"] as? String ?? ""
                          let phone = data["phone"] as? String ?? ""
                          let newPerson = ["name": name, "email": email, "phone": phone]
                          self.peopleArray.append(newPerson)
                          print(self.peopleArray)
                      }
                      self.table.reloadData()
                  }
              }
          }
      }
  </code></pre>
  
  <p>The first thing wrong here is that there is this error:</p>
  
  <blockquote>
    <p>Cannot convert value of type '[String : String]' to expected argument type '[Any]'</p>
  </blockquote>
  
  <p>When I try to append a newPerson in the PeopleArray. I have searched this up, but none of the answers matched this specific error. The second thing is that I have no clue how to even start adding the data from the PeopleArray into the Table View. </p>
  
  <p>I would love some help for both the error and the Table View. Anything is appreciated!</p>
  
  <p>––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––</p>
  
  <p>After doing what Vadian recommended, I am stuck with a new error. </p>
  
  <blockquote>
    <p>attempt to insert row 2 into section 0, but there are only 1 rows in section 0 after the update</p>
  </blockquote>
  
  <p>This is the updated func loadData:</p>
  
  <pre><code>func loadData() {
      FirebaseFirestore.root.collection("users").getDocuments { (snapshot, error) in
          if let error = error {
              print(error.localizedDescription)
          } else {
              if let snapshot = snapshot {
  
                  for document in snapshot.documents {
                      self.table.beginUpdates()
  
                      let data = document.data()
                      let name = data["name"] as? String ?? ""
                      let zip = data["zip"] as? String ?? ""
                      let sport = data["sport"] as? String ?? ""
                      let newPerson = Person(name: name, zip: zip, sport: sport)
                      self.people.append(newPerson)
  
                      let newIndexPath = IndexPath(row: self.people.count, section: 0)
                      self.table.insertRows(at: [newIndexPath], with: .automatic)
                      self.table.endUpdates()
                  }
                  DispatchQueue.main.async {
                      self.table.reloadData()
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>I've read about this on another question about how the rows are off by 1, but even when I let indexPath equal to <code>people.count+1</code> or <code>people.count+2</code>, the error persists. What am I doing wrong?</p>