我正在使用Firestore后端构建应用程序,并且我尝试使用当前用户的设置页面信息调用文档。在更新空数组时,我能够做到这一点没有问题,但是在尝试填充单个文档时遇到了可怕的时间。我有一个名为template<typename T1, typename T2>
void func(T1, T2) = delete;
long func(long a, long b)
{
static_assert(std::is_same<long,decltype(a+b)>::value,"!!");
return a+b;
}
的自定义对象:
DxUser
在视图控制器中,我正在尝试使用当前用户更新此变量,但我只能在闭包中抓取它,并且它在块外的任何位置填充为nil。这是我正在使用的基本代码,但任何人都可以告诉我我错过了什么吗?
struct DxUser {
var email:String?
var name:String?
var timeStamp:Date?
var profileImageURL:String?
var ehr: String?
var dictionary:[String:Any]? {
return [
"email":email,
"name":name,
"timeStamp":timeStamp,
"profileImageURL":profileImageURL,
"ehr": ehr as Any
]
}
}
extension DxUser : DocumentSerializable {
init?(dictionary: [String : Any]) {
guard let email = dictionary["email"] as? String,
let name = dictionary["name"] as? String,
let timeStamp = dictionary["timeStamp"] as? Date,
let profileImageURL = dictionary["profileImageURL"] as? String,
let ehr = dictionary["ehr"] as? String else {return nil}
self.init(email: email, name: name, timeStamp: timeStamp, profileImageURL: profileImageURL, ehr: ehr)
}
}
是的,这就是我在桌面视图中的表现方式,但我没有看到常规VC上的任何可比性。
class SettingsController: UIViewController {
var dxUser = DxUser()
override func viewDidLoad() {
super.viewDidLoad()
fetchUser()
}
func fetchUser() {
guard let uid = Auth.auth().currentUser?.uid else {
return
}
let userRef = db.collection("users").document(uid)
userRef.getDocument { (document, error) in
if error != nil {
print(error as Any)
} else {
self.dxUser = DxUser(dictionary: (document?.data())!)!
self.navigationItem.title = self.dxUser.name
print (self.dxUser)
}
}
}
答案 0 :(得分:1)
与您访问dxUser的位置位置并非如此。这是时间。 Firebase API是异步的,这意味着userRef.getDocument()
会立即返回,并且只有在请求完成后才会收到回调。如果您在dxUser
方法中尝试在该呼叫后立即访问fetchUser()
,则该请求将无法使用,因为请求未完成。鉴于异步API的工作原理,您应该只在调用调用后调用dxUser
,这通常意味着延迟在您的应用中呈现该数据(例如您的print语句所在的位置)
Please read more here了解为什么Firebase API是异步的,以及您可以从中获得什么。
答案 1 :(得分:0)
我实际上已经明白了。我将fetchUser()函数拉出到viewWillAppear函数,所以我在视图出现之前调用它。然后我做了异步函数来重新运行viewDidLoad。其他人有什么更好的建议吗?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
fetchUser()
}
func fetchUser() {
let userRef = db.collection("users").document(uid)
userRef.getDocument { (document, error) in
if error != nil {
print(error as Any)
} else {
self.dxUser = DxUser(dictionary: (document?.data())!)!
DispatchQueue.main.async {
self.viewDidLoad()
}
self.navigationItem.title = self.dxUser.name
}
}
}