【发布时间】:2018-10-11 09:53:18
【问题描述】:
我的代码从 Firestore 检索数据时遇到问题。
我的代码中有 2 个类:Exercise 和 Tag。 我的 FirestoreDatabase 中有 2 个集合:练习和标签
我需要从“练习”集合中获取所有“练习”文档。每个“练习”文档都有一个名为“标签”的字段,它是一个字符串数组。数组的每个字符串都包含引用“tag”在“tags”集合中的文档的“id”。因此,在“tags”集合中查询这个 id,使我能够获得正确的“tag”文档并访问其所有数据。这正是我想要在我的代码中做的。
我需要将所有练习添加到一个练习对象中,为此我必须在另一个 getDocument 查询中使用 getDocument 查询,以便从“标签”集合中获取练习的“标签”
这是我的课程标签和练习:
class Tag {
var id: String?
var type: String?
var description: String?
init(id: String, type: String, description: String) {
self.id = id
self.type = type
self.description = description
}
}
class Exercise {
let id: String?
let group: String?
let tags: [Tag]
let title : String!
init(id: String, group: String, tags: [Tag], title: String){
self.id = id
self.group = group
self.tags = tags
self.title = title
}
}
这是我从 Firestore 数据库中获取“练习”的代码:
func fetchExercises(completion: @escaping ([Exercise]) -> ()) {
let exercisesRef = Firestore.firestore().collection("exercises")
exercisesRef.getDocuments() { (querySnapshot, err) in
var exercisesArray = [Exercise]()
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
//print("\(document.documentID) => \(document.data())")
let myData = document.data()
let exercise_ID = document.documentID
let exercise_group = myData["Group"] as! String
let tagsArray = myData["Tags"] as! [String]
var exercise_tags: [Tag] = [Tag]()
for tag in tagsArray {
let tagID: String = tag
fetchTagfromID(tagID: tagID) { (tag: Tag) in
exercise_tags.append(tag)
}
}
let exercise_title = myData["Title"] as! String
exercisesArray.append(Exercise(id: exercise_ID,
group: exercise_group,
tags: exercise_tags,
title: exercise_title,
))
}
DispatchQueue.main.async{
print("EXERCISE FETCH HAS FINIS")
completion(exercisesArray)
}
}
}
}
func fetchTagfromID(tagID: String, completion: @escaping (Tag) -> ()) {
let tagRef = Firestore.firestore().collection("tags").document(tagID)
tagRef.getDocument() { (document, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
let myData = document?.data()
let tagDescription: String = myData!["description"] as! String
let tagType: String = myData!["type"] as! String
let tag: Tag = Tag(id: tagID, type: tagType, description:
tagDescription)
DispatchQueue.main.async{
print("TAGS FETCH HAS FINISHED")
completion(tag)
}
}
}
}
我的问题在于执行时间(队列)代码。
我需要先填写“exercise_tags”(辅助 getDocument 查询),然后继续并完成 fetchExercise(主要 getDocument 查询),但 Firestore 不允许(或不知道如何)这样做。代码首先完成主 getDocument 查询 (fetChExercises),然后返回完成辅助 getDocument 查询 (fetchTagfromID)。
总之,我需要在运行时得到这个日志:
TAGS FETCH HAS FINISHED
EXERCISES FETCH HAS FINISHED
现在我的情况正好相反。
你们知道如何解决这个问题吗?也许改变调度队列......
我现在如何分两步解决这个问题,但优雅的解决方案是一步完成所有事情。这就是 fetchExercises。
谢谢!
【问题讨论】:
标签: ios swift google-cloud-firestore