我正在构建一个Firestore后端的am应用程序,并试图调用一个文档,其中包含当前用户的设置页面信息。在更新空数组时,我可以做到这一点,但在尝试填充单个文档时遇到了困难。我有一个名为DxUser的自定义对象:

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)
    }
}

在视图控制器中,我试图用当前用户更新这个变量,但是我只能在闭包中获取它,并且它在块之外的任何地方填充为nil。这是我正在使用的基本代码,但有谁能告诉我缺少什么吗?
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)
        }
    }
}

是的,这就是我在桌面视图上做的,但是我没有看到任何可以与普通VC相比的东西。
db.collection("users").document(uid!).collection("goals").getDocuments { (snapshot, error) in
        if error != nil {
            print(error as Any)
        } else {
            //set the profile array to equal whatever I am querying below
            goalsArray = snapshot!.documents.flatMap({Goal(dictionary: $0.data())})
            DispatchQueue.main.async {
                self.collectionView?.reloadData()
            }
        }
    }

最佳答案

这与你可以访问dxUser的位置无关。是时候了。firebaseapi是异步的,这意味着userRef.getDocument()会立即返回,并且只有在请求完成后才会收到回调。如果您尝试在调用之后在dxUser方法中访问fetchUser(),它将不可用,因为请求未完成。鉴于异步api就是这样工作的,您应该只在调用回调之后使用dxUser,这通常意味着延迟应用程序中数据的呈现(例如print语句所在的位置)。
Please read more here关于为什么firebaseapi是异步的,以及您对它们的期望。

10-08 11:35