0

this seems like it should be quite a simple thing to do, but can't seem to find a solution. I have some data in Firestore held in an array that I need to get and place into and two dimensional array inside my swift app. I'm pretty noob so apologies in advance!

This is the data I'm trying to get from Firestore firestore

This is the code I'm using to query my documents and then loop through the result, extracting the data

fireStoreDatabase.collection("Posts").whereField("postedTo", arrayContains: userId).order(by: "date", descending: true).addSnapshotListener { (snapshot, error) in
        if error != nil {

            print(error?.localizedDescription)
        } else {
            if snapshot?.isEmpty != true && snapshot != nil {
                print("Posted data got")
                
                //clear the arrays to stop duplicates when we do an upload and pull in the data again
                self.postedShoutTextArray.removeAll(keepingCapacity: false)
                self.postedByArray.removeAll(keepingCapacity: false)
                self.postedDateArray.removeAll(keepingCapacity: false)
                self.postedQuestionsArray.removeAll(keepingCapacity: false)
                
                //loop through the firestore
                for document in snapshot!.documents {
                    //add data to the arrays
                    if let shoutText = document.get("shoutText") as? String {
                        self.postedShoutTextArray.append(shoutText)
                    }
                    if let postedBy = document.get("postedBy") as? String {
                        self.postedByArray.append(postedBy)
                    }
                    if let date = document.get("date") as? String {
                        self.postedDateArray.append(date)
                    }
                    
                    if let pollQuestions = document.get("pollQuestions") as? [String] {
                        self.postedQuestionsArray = pollQuestions
                    } else {
                        print("no array data")
                    }

                    self.receivedCollectionView.reloadData()
                }
                
            } else {
                print("GET POSTED MESSAGES no data")
            }
            
        }
    }

So I'd like the data to go into a two dimensional array (if that's possible) containing the data from the pollQuestions array for each document I loop through (does that make sense?).

Been searching all over, and seen references to map etc, but had no luck finding a solution.

Any help appreciated!

1
  • Ok apologies, the data is now coming out of firestore using the above code, so I've solved part of the problem as I couldn't even get to the data before. But how do loop through the data and put it into a 2D array? Commented May 26, 2021 at 21:14

1 Answer 1

3

Rather than storing each property in a separate array, you may want to consider representing it with a struct. Something like:

struct Item {
    var shoutText: String?
    var postedBy: String?
    var date: String?
    var pollQuestions : [String]
}

Then, on your view controller, declare a property:

var items: [Item] = []

Then, in your snapshot listener, you can populate that array:

func getData() {
    Firestore.firestore().collection("Posts").whereField("postedTo", arrayContains: userId).order(by: "date", descending: true).addSnapshotListener { (snapshot, error) in
        if error != nil {
            print(error?.localizedDescription)
        } else {
            if let snapshot = snapshot, !snapshot.isEmpty {
                print("Posted data got")
                
                self.items = snapshot.documents.map { document in
                    Item(shoutText: document.get("shout") as? String,
                         postedBy:  document.get("postedBy") as? String,
                         date: document.get("date") as? String,
                         pollQuestions: document.get("pollQuestions") as? [String] ?? [])
                }
                
                self.receivedCollectionView.reloadData()
                
            } else {
                print("GET POSTED MESSAGES no data")
            }
            
        }
    }
}

Later, you can access this data:

self.items[itemIndex].pollQuestions[pollQuestionIndex]
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks this looks great, I'll give it a try now
Excellent answer and thank you for giving my data some better structure too
in my previous multi-array setup I had to clear the arrays before loading more data to avoid duplicates, do I need to do that with a struct too?
No -- the line self.items = replaces whatever was previously in items with the new data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.