Firestore使用for循环查询多个文档

时间:2020-01-02 19:46:21

标签: ios swift google-cloud-firestore

我正在尝试使用for-loop查询多个文档。

我的数据库设置如下:

用户->愿望清单->所有用户的愿望清单(包含带有name的不同的愿望清单)->wünsche

正在检索项目,但顺序错误。我尝试了几种不同的方法,但到目前为止没有任何效果。

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
    }

    for list in self.dataSourceArray {
         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{
                // create 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))
                }

                self.dataSourceArray[counter].wishData = wList
                counter += 1
            }
        }
    }
}

我正在另一个函数内调用此函数,该函数以正确的顺序检索所有wishlist

func getWishlists() {
    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])
                }

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

            }
        }
        self.theCollectionView.isHidden = false
        self.getWishes()
    }
}

* DataSourceArray的正确顺序:* 主要愿望清单,目标,提升

第二次print测试的输出: ,目标,主要愿望清单

1 个答案:

答案 0 :(得分:0)

似乎您正在尝试一次进行一堆API调用,并且它在不同时间返回值。您可以尝试同步进行呼叫以维持顺序,也可以尝试使用调度组,例如下面的伪代码:

let myGroup = DispatchGroup()

struct DataItem {
    let order: Int
    let data: DataYouWantToSave
}

var fetchedData = [DataItem]()

for i in list {
    myGroup.enter()

    let dataItem = DataItem()
    dataItem.order = i

    db.collection...
        print("Finished request \(i)")
        dataItem.data = DataYouWantToSave
        fetchedData.apped(dataItem)
        myGroup.leave()
    }
}

myGroup.notify(queue: .main) {
    print("Finished all requests.")
    // Reorder your array of data items here.
    let sortedArray = fetchedData.sorted(by: { $0.order > $1.order })

    // If you just want the array of data values
    let newData: [DataYouWantToSave] = sortedArray.map { $0.data }
}