ios Firestore查询完成

46scxncf  于 2023-02-26  发布在  iOS
关注(0)|答案(1)|浏览(107)

我正在调用一个Firestore查询,它确实会返回,但我需要确保在继续执行其余代码之前完成,所以我需要一个完成处理程序......但对于我的生活来说,我似乎无法编写它。
正如评论所建议的那样,我尝试使用异步/等待调用:功能:

// get user info from db
    func getUser() async {
        self.db.collection("userSetting").getDocuments() { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {
                    let userTrust = document.data()["userTrust"] as! String
                    let userGrade = document.data()["userGrade"] as! String
                    let userDisclaimer = document.data()["userDisclaimer"] as! String
                    
                    var row = [String]()
                    row.append(userTrust)
                    row.append(userGrade)
                    row.append(userDisclaimer)
                    
                    self.userArray.append(row)
                    
                    // set google firebase analytics user info
                    self.userTrustInfo = userTrust
                    self.userGradeInfo = userGrade

                }
            }
            
        }
    }

电话:

internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        FirebaseApp.configure()
        db = Firestore.firestore()
        Database.database().isPersistenceEnabled = true

        Task {
            do {
                let userInfo = await getUser()
            }
        } return true }

我使用了一个任务,因为didFinishLauncingWithOptions是同步的,而不是异步的
但是,在didFinishLauncingWithOptions继续之前,getUser()仍然没有完成。
我需要getUser的数据,因为下一个步骤使用数组中的数据,如果没有它,我会得到一个"越界异常",因为数组仍然是空的。
还尝试在func getUser()中使用调度组。同样没有效果。
最后尝试完成处理程序:

func getUser(completion: @escaping (Bool) -> Void) {

        self.db.collection("userSetting").getDocuments() { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            } else {

                for document in querySnapshot!.documents {

                    let userTrust = document.data()["userTrust"] as! String
                    let userGrade = document.data()["userGrade"] as! String
                    let userDisclaimer = document.data()["userDisclaimer"] as! String
                    
                    var row = [String]()
                    row.append(userTrust)
                    row.append(userGrade)
                    row.append(userDisclaimer)
                    
                    self.userArray.append(row)
                    
                    // set google firebase analytics user info
                    self.userTrustInfo = userTrust
                    self.userGradeInfo = userGrade
                    
                    completion(true)
                    }
                
                }
            }
        
        }

没有任何效果。getUser调用在代码继续运行之前没有完成。有人能帮帮我吗?我已经搜索了很多次,查看了所有链接的答案,但我不能使这个工作。我显然错过了一些简单的东西,请帮帮我

xfb7svmp

xfb7svmp1#

下面是一个使用completion-handler方法的工作函数的例子。在深入到async-await之前,我将使用这个方法,因为它要简单得多。使用async-await,在代码库的更大架构中有更多的事情要考虑(即使用参与者,分配主要参与者,使用分离或附加任务,等等)。

func getUser(_ completion: @escaping (_ done: Bool) -> Void) {
    self.db.collection("userSetting").getDocuments() { (snapshot, err) in
        guard let snapshot = snapshot else {
            if let error = error {
                print(error)
            }
            completion(false) // always call the completion handler before leaving
            return // terminate this function call
        }
        for doc in snapshot.documents {
            
            // Unwrap the fields in the document safely. You don't want to crash
            // the entire app because you weren't able to get a string from a
            // document read.
            if let userTrust = doc.get("userTrust") as? String,
               let userGrade = doc.get("userGrade") as? String,
               let userDisclaimer = doc.get("userDisclaimer") as? String {
                let row = [userTrust, userGrade, userDisclaimer]
                self.userArray.append(row)
            }
        }
        
        // Once you've finished parsing the documents, call the completion.
        completion(true)
    }
}

getUser { done in
    if done {
        // do something
    } else {
        // do something else
    }
}

我不明白的是,为什么要从集合中获取一堆文档,然后在每个文档循环中执行以下操作:

self.userTrustInfo = userTrust
self.userGradeInfo = userGrade

您是想只获取用户的设置文档,还是想查询整个文档集合?

相关问题