Swift - Firebase - order collection

为君一笑 提交于 2020-01-10 05:56:04

问题


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


回答1:


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()



回答2:


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.




回答3:


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 :)



来源:https://stackoverflow.com/questions/59556505/swift-firebase-order-collection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!