我正在调用一个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调用在代码继续运行之前没有完成。有人能帮帮我吗?我已经搜索了很多次,查看了所有链接的答案,但我不能使这个工作。我显然错过了一些简单的东西,请帮帮我
2条答案
按热度按时间owfi6suc1#
阅读此帖子:Waiting for data to be loaded on app startup.
它解释了为什么在从函数
application(_:didFinishLaunchingWithOptions)
返回之前不应该等待数据。要实现您的需要,您可以将第一个ViewController用作一种闪屏(只显示图像或活动指示器),并在
viewDidLoad()
方法中调用函数getUser(completion:)
ViewController。示例:
其中
MyFirestoreDatabaseManager.shared
显然是在其上定义getUser(completion:)
方法的对象。(In在你的例子中,我认为你在AppDelegate中定义了那个函数。在这种情况下,你应该把你的
getUser(completion:)
方法和所有相关变量标记为static
。然后用AppDelegate
替换MyFirestoreDatabaseManager.shared
)。slmsl1lt2#
我不能100%确定你想要完成什么,因为我看不到你所有的代码,但是尝试类似的东西,替换你试图从文档返回的对象。
你不希望你的用户数据分散在多个文档中。使用Firebase,你需要为你必须获得的每个文档付费。理想情况下,你希望你的所有用户设置都在一个Firebase文档中。然后创建一个UserInfo结构体,你可以使用库CodeableFirebase或你选择的解码器解码到该结构体。
你就能做到...