【发布时间】:2021-04-23 21:11:15
【问题描述】:
我想实现一个文本字段来显示当前用户在数据库(Firestore)中的现有分数。由于 Firebase 查询中异步的性质,我还需要对我的代码进行一些调整。但是,completion() 处理程序似乎无法正常工作:
// ViewModel.swift
import Foundation
import Firebase
import FirebaseFirestore
class UserViewModel: ObservableObject {
let current_user_id = Auth.auth().currentUser!.uid
private var db = Firestore.firestore()
@Published var xp:Int?
func fetchData(completion: @escaping () -> Void) {
let docRef = db.collection("users").document(current_user_id)
docRef.getDocument { snapshot, error in
print(error ?? "No error.")
self.xp = 0
guard let snapshot = snapshot else {
completion()
return
}
self.xp = (snapshot.data()!["xp"] as! Int)
completion()
}
}
}
// View.swift
import SwiftUI
import CoreData
import Firebase
{
@ObservedObject private var users = UserViewModel()
var body: some View {
VStack {
HStack {
// ...
Text("xp: \(users.xp ?? 0)")
// Text("xp: 1500")
.fontWeight(.bold)
.padding(.horizontal)
.foregroundColor(Color.white)
.background(Color("Black"))
.clipShape(CustomCorner(corners: [.bottomLeft, .bottomRight, .topRight, .topLeft], size: 3))
.padding(.trailing)
}
.padding(.top)
.onAppear() {
self.users.fetchData()
}
// ...
}
}
我的结果在Text("xp: \(users.xp ?? 0)") 中一直显示为 0,这表示该步骤尚未异步。那我该怎么解决呢?
【问题讨论】:
-
您没有显示
fetchData的调用位置。另外,您确定self.xp被分配了吗?您是否设置了断点或打印语句以确保获得您期望的值? -
在这种情况下完成处理程序应该做什么也不是很清楚。您的视图将自动响应 @Published 属性,进一步强化了代码实际上可能没有成功到达或分配
self.xp的想法 -
好吧,我只是相信因为 Firebase 总是异步检索数据,completion() 处理程序有助于指示此步骤需要在任何其他步骤之前完成。你的意思是completion()在这里没用吗?
-
您在编辑中添加的调用站点似乎甚至无效(它没有为完成处理程序提供参数。所以,是的,出于这个原因和我上面说了,这里好像没啥用。
标签: swift firebase asynchronous google-cloud-firestore swiftui