Firebase获取的学校ID可在弹窗显示却无法在普通VC文本框展示
核心问题定位
你遇到的文本框空白问题,本质是对Firestore getDocuments的异步执行时序理解偏差:
getDocuments属于异步网络请求,不会阻塞当前线程等待数据返回- 你当前的函数实现是:刚发起网络请求,不等回调里的赋值逻辑执行完成,就直接读取类成员变量
skoolID的旧值做字符串截取、同步返回——此时网络请求尚未完成,skoolID还没被赋值,返回的自然是空字符串 - 之前弹窗里能正常展示ID,属于偶发的时序巧合:要么是你之前已经在其他页面触发过同查询、提前完成了
skoolsID的赋值,要么是弹窗弹出的延迟刚好赶上网络回调执行完成;换到独立页面调用时没有这些巧合,就直接暴露了空值问题。
现存的冗余脆弱逻辑
你当前通过把模型对象转字符串、再硬删除前后字符提取schoolID的写法非常不可靠:
- 只要模型的默认字符串输出格式发生变化,截取位置就会完全错误
- 完全没有必要绕这个弯,直接从查询结果中读取对应字段即可
可直接落地的修正方案
- 把获取ID的函数改为通过闭包回调返回结果,放弃无意义的同步return写法
- 移除硬截字符串的冗余逻辑,直接从查询结果中提取需要的school_id值
- 网络回调完成后,切回主线程完成UI文本框的赋值操作
改造后的通用ID获取函数
func fetchSchoolID(completion: @escaping (String?) -> Void) { guard let currentUserID = user?.uid else { completion(nil) return } db.collection("school_users") .whereField("userID", isEqualTo: currentUserID) .getDocuments { querySnapshot, err in if let err = err { print("There was an error fetching the documents: \(err)") completion(nil) return } guard let targetDoc = querySnapshot?.documents.first, let schoolID = targetDoc.get("school_id") as? String else { completion(nil) return } completion(schoolID) } }
新增事件页的正确调用逻辑
替换原viewDidLoad中的错误调用:
public override func viewDidLoad() { super.viewDidLoad() errLabel.alpha = 0 fetchSchoolID { [weak self] schoolID in // 网络回调不在主线程,UI操作必须切回主线程执行 DispatchQueue.main.async { self?.schoolIDTextF.text = schoolID ?? "" } } }
兼容原有弹窗逻辑的调用方式
如果要保留原弹窗的展示效果,直接复用上面的通用函数即可,不用维护两份重复代码:
@IBAction func infoPressed(_ sender: UIBarButtonItem) { let alert = UIAlertController(title: "User Info", message: "School ID", preferredStyle: .alert) let dismissAction = UIAlertAction(title: "Dismiss", style: .cancel) { _ in self.dismiss(animated: true, completion: nil) } alert.addTextField { alertTextField in alertTextField.isEnabled = false // 等异步拿到ID后再给弹窗文本框赋值 self.fetchSchoolID { schoolID in DispatchQueue.main.async { alertTextField.text = schoolID ?? "" } } } alert.addAction(dismissAction) present(alert, animated: true, completion: nil) }
额外提醒:原代码中连续两次调用
getTheSchoolID()的写法,除了拿不到异步值的问题,还会重复发起两次完全相同的网络请求,造成不必要的流量消耗。
内容的提问来源于stack exchange,提问作者dsonawave
相关产品推荐
相关产品推荐

