Juan Camilo
Juan Camilo

Reputation: 27

How can I convert the downloaded data from Firestore to an array and assign it to my table view?

I'm capturing Firestore data as Firebase shows us, but I don't know how to save the query I make.

In conclusion, what I want to do is bring all the documents that have the same value in your pid field, and then show in a table the product fields and start date, each document in a different cell.


collection food

document: 1

     pid:john1
     product:Ice
     startDate:01/01/2010

document: 2

     pid:john1
     product:Rice
     startDate:01/02/2010

I need to show in the table:


Ice was bought on 01/01/2010


Rice was bought on 01/02/2010


I have this code:

func loadFood(){
        pid = "john1"
        db = Firestore.firestore()
        db.collection("food").whereField("pid", isEqualTo: pid)
        .addSnapshotListener { querySnapshot, error in
            guard let documents = querySnapshot?.documents else {
                print("\n--------------------------------------")
                print("Error document: \(error!)")
                print("--------------------------------------\n")
                return
            }

            let startDate = documents.map { $0["startDate"]! }
            let product = documents.map {$0["product"]!}

            let message = ("\(product) was bought \(startDate)")
            self.dataRecord.insert(message, at: 0)
            DispatchQueue.main.async {
                self.tvRecord.reloadData()
            }
        }
    }

I'm showing in the table:


[Ice, Rice] was bought on [01/01/2010, 01/02/2010]


Upvotes: 1

Views: 249

Answers (2)

slushy
slushy

Reputation: 12385

You make a couple of mistakes. First, you loop over the documents multiple times, unnecessarily; that's not very efficient. In your case, you should loop over them once and do all of your data prep in each loop iteration. Second, Firestore has a method specifically for extracting data from document fields called get() which is very easy to read and efficient.

func loadFood(){

    pid = "john1"

    Firestore.firestore().collection("food").whereField("pid", isEqualTo: pid).addSnapshotListener { querySnapshot, error in

        guard let documents = querySnapshot?.documents else {
            print("\n--------------------------------------")
            print("Error document: \(error!)")
            print("--------------------------------------\n")
            return
        }

        for doc in documents {

            guard let startDate = doc.get("startDate") as? String,
                let product = doc.get("product") as? String else {
                    continue // continue this loop, not "return" which will return control out of the calling function
            }

            let message = "\(product) was bought \(startDate)"
            dataRecord.append(message)

        }

        DispatchQueue.main.async {
            self.tvRecord.reloadData()
        }

    }

}

Upvotes: 2

Shehata Gamal
Shehata Gamal

Reputation: 100503

As you deal with the 2 arrays as if they are 1 string instead you need

struct Item {
  let message,startDate:String
}

Then

var dataRecord = [Item]()

and finally

self.dataRecord  = documents.map {  Item(message:$0["product"]!,startDate:$0["startDate"]!)} 

Upvotes: 0

Related Questions