I want to display the school id in a textfield of a certain view controller but I can't for some reason. I have a function that gets the school ID, of the current School user, and I am able to display it in an alertVC but not a regular VC. I will add images and explanations.
First, I will show my code for the function that gets the school ID for the current user and displays it in the alertVC.
func getTheSchoolsID() -> String {
db.collection("school_users").whereField("userID", isEqualTo: user?.uid).getDocuments { (querySnapshot, err) in
if let err = err {
print("There was an error fetching the documents: \(err)")
} else {
self.skoolsID = querySnapshot!.documents.map { document in
return SchoolID(schoolID: (document.get("school_id") as! String ?? ""))
}
self.tableView.reloadData()
}
}
let fixID = "\(skoolsID)"
let substring = fixID.dropFirst(28).dropLast(3)
let realString = String(substring)
return realString
}
Here is the code for the alertVC as well.
@IBAction func infoPressed(_ sender: UIBarButtonItem) {
var text = UITextField()
let alert = UIAlertController(title: "User Info", message: "School ID", preferredStyle: .alert)
let action = UIAlertAction(title: "Dismiss", style: .cancel) { (action) in
self.dismiss(animated: true, completion: nil)
}
alert.addTextField { (alertTextField) in
alertTextField.text = self.getTheSchoolsID()
alertTextField.isEnabled = false
}
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
These two produce this outcome.
This is the exact school_id that is in the document as well.
Now, when I want to display this exact same value in a textfield of the other VC where I add a new event, it shows nothing.
The code is exactly the same as the first code snippet, except for reloadData(), which makes sense, and It doesn't produce the same outcome.
func getTheSchoolID() -> String {
db.collection("school_users").whereField("userID", isEqualTo: user?.uid).getDocuments { (querySnapshot, err) in
if let err = err {
print("There was an error fetching the documents: \(err)")
} else {
self.skoolID = querySnapshot!.documents.map { document in
return SchoolID(schoolID: (document.get("school_id") as! String ?? ""))
}
}
}
let fixedID = "\(skoolID)"
let substring = fixedID.dropFirst(28).dropLast(3)
let realString = String(substring)
return realString
}
Here is me trying to declare it as well.
public override func viewDidLoad() {
super.viewDidLoad()
errLabel.alpha = 0
getTheSchoolID()
schoolIDTextF.text = getTheSchoolID()
// Do any additional setup after loading the view.
}
If anybody can help with this problem it would be greatly appreciated. I tried to explain it as best as I possibly could. I know there's a lot of information, but if you still need more I can clarify in the comments. Thanks.
GetSchoolIds from the firestore collection is the asynchronous task. So using the closure you can achieve this.
func getTheSchoolsID(completion:@escaping(_ schoolIds:[SchoolID]?) -> Void) {
db.collection("school_users").whereField("userID", isEqualTo: user?.uid).getDocuments { (querySnapshot, err) in
if let err = err {
print("There was an error fetching the documents: \(err)")
completion(nil)
} else {
let schoolsId = querySnapshot!.documents.map { document in
return SchoolID(schoolID: (document.get("school_id") as! String ?? ""))
}
completion(schoolsId)
}
}
}
Use this function to your VC
override func viewDidLoad() {
super.viewDidLoad()
errLabel.alpha = 0
getTheSchoolsID(completion: {
[weak self] schoolIds in
if let schoolIdObj = schoolIds?.first {
let substring = schoolIdObj.schoolID.dropFirst(28).dropLast(3)
let realString = String(substring)
DispatchQueue.main.async {
self?.schoolIDTextF.text = realString
}
}
})
}