Chris
Chris

Reputation: 2274

Swift - Firebase - order collection

I am trying to retrieve some documents but I need them to be ordered by some data ("ListIDX") inside my "Wishlists" - collection.

I tried this but that's not allowed:

db.collection("users").document(userID).collection("wishlists").order(by: "ListIDX").document(list.name).collection("wünsche").getDocuments()

This is my function:

    func getWishes (){
            let db = Firestore.firestore()
            let userID = Auth.auth().currentUser!.uid

            var counter = 0

            for list in self.dataSourceArray {
print(list.name) // -> right order
                db.collection("users").document(userID).collection("wishlists").document(list.name).collection("wünsche").getDocuments() { ( querySnapshot, error) in
print(list.name) // wrong order
                    if let error = error {
                        print(error.localizedDescription)
                    }else{
                        // DMAG - create a new Wish array
                        var wList: [Wish] = [Wish]()
                        for document in querySnapshot!.documents {
                            let documentData = document.data()
                            let wishName = documentData["name"]
                            wList.append(Wish(withWishName: wishName as! String, checked: false))
                        }
                        // DMAG - set the array of wishes to the userWishListData
                        self.dataSourceArray[counter].wishData = wList
                        counter += 1
                    }
                }
            }
        }

This is what I actually would like to achieve in the end:

self.dataSourceArray[ListIDX].wishData = wList

Update

I also have a function that retrieves my wishlists in the right order. Maybe I can add getWishesin there so it is in the right order as well.

    func retrieveUserDataFromDB() -> Void {

        let db = Firestore.firestore()
        let userID = Auth.auth().currentUser!.uid
        db.collection("users").document(userID).collection("wishlists").order(by: "listIDX").getDocuments() { ( querySnapshot, error) in
            if let error = error {
                print(error.localizedDescription)
            }else {
                // get all documents from "wishlists"-collection and save attributes
                for document in querySnapshot!.documents {
                    let documentData = document.data()
                    let listName = documentData["name"]
                    let listImageIDX = documentData["imageIDX"]

                    // if-case for Main Wishlist
                    if listImageIDX as? Int == nil {
                        self.dataSourceArray.append(Wishlist(name: listName as! String, image: UIImage(named: "iconRoundedImage")!, wishData: [Wish]()))
                        // set the drop down menu's options
                        self.dropDownButton.dropView.dropDownOptions.append(listName as! String)
                        self.dropDownButton.dropView.dropDownListImages.append(UIImage(named: "iconRoundedImage")!)
                    }else {

                        self.dataSourceArray.append(Wishlist(name: listName as! String, image: self.images[listImageIDX as! Int], wishData: [Wish]()))

                        self.dropDownButton.dropView.dropDownOptions.append(listName as! String)
                        self.dropDownButton.dropView.dropDownListImages.append(self.images[listImageIDX as! Int])
                    }

//                    // create an empty wishlist
//                    wList = [Wish]()
//                    self.userWishListData.append(wList)

                    // reload collectionView and tableView
                    self.theCollectionView.reloadData()
                    self.dropDownButton.dropView.tableView.reloadData()

                }

            }
            self.getWishes()
        }

For a better understanding:

git repo

Upvotes: 0

Views: 226

Answers (3)

Chris
Chris

Reputation: 2274

I solved the problem. I added another attribute when saving a wish that tracks the index of the list it is being added to. Maybe not the smoothest way but it works. Thanks for all the help :)

Upvotes: 0

Alex Mamo
Alex Mamo

Reputation: 138824

I am trying to retrieve some documents but I need them to be ordered by some data ("ListIDX")

The following line of code will definitely help you achieve that:

db.collection("users").document(userID).collection("wishlists").order(by: "ListIDX").getDocuments() {/* ... */}

Adding another .document(list.name) call after .order(by: "ListIDX") is not allowed because this function returns a Firestore Query object and there is no way you can chain such a function since it does not exist in that class.

Furthermore, Firestore queries are shallow, meaning that they only get items from the collection that the query is run against. There is no way to get documents from a top-level collection and a sub-collection in a single query. Firestore doesn't support queries across different collections in one go. A single query may only use the properties of documents in a single collection. So the most simple solution I can think of would be to use two different queries and merge the results client-side. The first one would be the above query which returns a list of "wishlists" and the second one would be a query that can help you get all wishes that exist within each wishlist object in wünsche subcollection.

Upvotes: 1

Puteri
Puteri

Reputation: 3789

As @algrid says, there is no sense to order the collection using order() if you are going to get an specific element using list.name at the end, not the first or the last. I would suggest to change your code to:

db.collection("users").document(userID).collection("wishlists").document(list.name).collection("wünsche").getDocuments()

Upvotes: 1

Related Questions