【问题标题】:I want to process after "getDocuments" processing is completed in FireStore我想在 FireStore 中完成“getDocuments”处理后处理
【发布时间】:2020-06-26 17:30:39
【问题描述】:

Firestore 包含“用户”和“帖子”的集合。 每个用户的文档都有一个“帖子”集合。 “Posts”有一个引用类型“post”,值为“posts/documentID”。

我想获取用户的帖子列表,我尝试用下面的代码实现,但是“print(self.postsData)”是空的。

我该怎么做?

class postFetcher: ObservableObject {
    @Published var postsData: [PostModel] = []
    private let userDefaults = UserDefaults.standard
    private let uid: String
    private var db: Firestore!
    private let dispatchGroup = DispatchGroup()
    private let dispatchQueue = DispatchQueue(label: "queue")

    init() {
        db = Firestore.firestore()
        uid = self.userDefaults.object(forKey: "userDataUid") as! String
        fetchPostsData()
    }

    func fetchPostsData() {
        self.db.collection("users").document(uid).collection("posts").getDocuments { (snaps, err) in

            guard let snaps = snaps else { return }

            for document in snaps.documents {
                self.dispatchGroup.enter()
                self.dispatchQueue.async(group: self.dispatchGroup) { [weak self] in
                    self?.asyncProcess(document: document) { () -> Void in
                        self?.dispatchGroup.leave()
                    }
                }
            }

            self.dispatchGroup.notify(queue: .main) {
                print(self.postsData)
            }
        }
    }

    func asyncProcess(document: QueryDocumentSnapshot, completion: () -> Void) {
        let refarence: DocumentReference = document.data()["post"] as! DocumentReference

        refarence.getDocument { (snap, err) in

            guard let snap = snap else { return }
            self.postsData.append(PostModel(
                documentId: snap.documentID,
                text: snap.data()!["text"] as! String
            ))
        }
        completion()
    }
}

【问题讨论】:

    标签: swift google-cloud-firestore


    【解决方案1】:

    您在错误的地方拨打completion()。它需要位于当前前面的花括号内。

    另外,您指的是来自不同线程的self.postsData。馊主意。将所有读取或写入共享数据的调用包装在一些公共调度队列中。更好的是,根本不共享数据!将结果交给完成处理程序。

    【讨论】:

    • 另外guard let snap = snap else { return } 是错误的。每条路径都必须调用完成处理程序。
    • 非常感谢。在“refarence.getDocument”的括号中写入“completion ()”会导致错误“Escaping Closure captures non-escaping parameter 'completion'”。
    • 是的,你必须指定它是@escaping
    猜你喜欢
    • 2018-08-14
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多