1

I have a problem related to query Firestore. Currently, I have Firestore structure as below.

enter image description here

I want to create a search system where the user has the option either to filter programme, status and category. Below is the source code for the filter:

var filterProg = ""
var filterStat = ""
var filterCat = ""

   @IBAction func filterButtonDidTapped(_ sender: Any) {
    self.agencyList.removeAll()

  db.collection("fund")


 .whereField("programme", isEqualTo: filterProg )


 .whereField("status", isEqualTo: filterStat )


 .whereField("category", isEqualTo: filterCat )

        .getDocuments()
            {
                (querySnapshot, err) in

                if let err = err
                {
                    print("Error getting documents: \(err)");
                }
                else
                {
                    //  var agencyNumber = 0
                    for document in querySnapshot!.documents {
                        let data = document.data()
                        let agencyy = data["age"] as? String ?? ""
                        let title = data["name"] as? String ?? ""
                        let agencyId = document.documentID
                        print(title)
                        print(agencyy)
                        print(agencyId)

                        let newModel = DisplayModel(agency: title, agencyId: agencyId)
                        self.agencyList.append(newModel)
                       // self.originalData.append(title)
                    }
                    self.tableView.reloadData()
                }
    }

}

from the code above variables filterProg, filterStat, and filterCat will change from an empty string "", to some string from UIPicker depend on users choice. The problem is, if the user decides to filter for filterProg (program) and filterStat (status) only, the variable fileterCat will remain empty string "". This caused data from firestore to display nothing. I have tried something like: check if the variable is an empty string or not as below:

let query = db.collection("fund")

if filterProg != "" {
 query.whereField("programme", isEqualTo: filterProg )
}

if filterProg != "" {
 query.whereField("status", isEqualTo: filterStat )
}
 if filterProg != "" {
 query.whereField("category", isEqualTo: filterCat )
}
    .getDocuments() //got error here
        {
            (querySnapshot, err) in

I got an error on .getDocuments()

Reference to member 'getDocuments' cannot be resolved without a contextual type

I am stuck with this problem for a week. Actually, is it possible to make filter option on Firestore?

madhatter989
  • 271
  • 1
  • 5
  • 14

2 Answers2

3

I don't believe this is possible at present, but a workaround may be to create your query depending on the outcome of testing your fields for valid strings.

var query: Query!

if /* some condition */ {

    query = db.collection("fund").whereField("programme", isEqualTo: filterProg)

} else if /* condition */ {

    query = db.collection("fund").whereField("status", isEqualTo: filterStat)

} // etc

query.getDocuments { (snapshot, error) in
            //
        }

Improvements to firestore queries are on the radar: https://github.com/firebase/firebase-js-sdk/issues/321

rbaldwin
  • 4,581
  • 27
  • 38
1

You'll need to first construct the base of your query:

let query = db.collection("fund")

Then add the conditions to your query based on the values the user entered:

if filterProg != "" {
 query = query.whereField("programme", isEqualTo: filterProg )
}
if filterProg != "" {
 query = query.whereField("status", isEqualTo: filterStat )
}
if filterProg != "" {
 query = query.whereField("category", isEqualTo: filterCat )
}

And then finally get the documents matching the query:

query.getDocuments() {
  (querySnapshot, err) in ...
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807