如何在Firestore中使用集合和子集合在数组中创建数组?

时间:2018-09-14 07:58:44

标签: ios arrays swift firebase google-cloud-firestore

我需要创建一个包含Categories数组的Questions数组。

struct CategoryFB {
    var title: String
    var id: Int
    var questions: [QuestionsFB]

    var dictionary: [String : Any] {
        return ["title" : title, 
                "id" : id]
    }
}

extension CategoryFB {
    init?(dictionary: [String : Any], questions: [QuestionsFB]) {
        guard let title = dictionary["title"] as? String, let id = dictionary["id"] as? Int else { return nil }

        self.init(title: title, id: id, questions: questions)
    }
}

Firestore具有以下结构

  1. Collection(“类别”)
  2. Document(“ some_id”)
  3. Collection(“问题”)

如何创建这样的数组?

array = [Category(title: "First", 
                  questions: [
                      Question("1"),
                      ...
                  ]), 
         ... ]

我的尝试是错误的:

db.collection("Categories").order(by: "id", descending: false).getDocuments {
    (querySnapshot, error) in
    if error != nil {
        print("Error when getting data \(String(describing: error?.localizedDescription))")
    } else {
        for document in querySnapshot!.documents {
            print(document.documentID)
            self.db.collection("Categories").document(document.documentID).collection("Questions").getDocuments(completion: { (subQuerySnapshot, error) in
                if error != nil {
                    print(error!.localizedDescription)
                } else {
                    var questionsArray: [QuestionsFB]?
                    questionsArray = subQuerySnapshot?.documents.compactMap({QuestionsFB(dictionary: $0.data())})
                    self.categoriesArray = querySnapshot?.documents.compactMap({CategoryFB(dictionary: $0.data(), questions: questionsArray!)})
                    print(self.categoriesArray![0].questions.count)
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                }
            })
        }
    }
}

1 个答案:

答案 0 :(得分:0)

这是我自己找到的解决方案。希望这会在将来对某人有所帮助。

func getData(completion: @escaping (_ result: [Any]) -> Void) {
    let rootCollection = db.collection("Categories")

    var data = [Any]()

    rootCollection.order(by: "id", descending: false).getDocuments(completion: {

        (querySnapshot, error) in

        if error != nil {
            print("Error when getting data \(String(describing: error?.localizedDescription))")
        } else {
            guard let topSnapshot = querySnapshot?.documents else { return }
            for category in topSnapshot {
                rootCollection.document(category.documentID).collection("Questions").getDocuments(completion: {
                    (snapshot, err) in

                    guard let snapshot = snapshot?.documents else { return }

                    var questions = [Question]()

                    for document in snapshot {
                        let title = document.data()["title"] as! String
                        let details = document.data()["details"] as! String
                        let article = document.data()["article"] as! String
                        let link = document.data()["link"] as! String
                        let id = document.data()["id"] as! String
                        let possibleAnswers = document.data()["possibleAnswers"] as! [String]
                        let rightAnswerID = document.data()["rightAnswerID"] as! Int

                        let newQuestion = Question(title: title, article: article, details: details, link: link, possibleAnswers: possibleAnswers, rightAnswerID: rightAnswerID, id: id)

                        questions.append(newQuestion)

                    }
                    let categoryTitle = category.data()["title"] as! String
                    let collectionID = category.data()["id"] as! Int


                    let newCategory = Category(title: categoryTitle, id: collectionID, questions: questions)


                    data.append(newCategory)

                    //Return data on completion
                    completion(data)
                })
            }
        }
    })
}