I'm having trouble fetching data from a child node in a Firebase Realtime Database reference. I'm uploading a job request detail node to my logged in customer reference, however when I try to fetch the node, my controller won't read it and display it on the screen. Is it because I have to set my fetch API function to fetch the most recent job request detail node that was recently added by doing .childAdded
instead if .value
? Or am I doing something wrong when I call the fetch function in my controller itself? The reason why I ask is because I try to print jobRequest in my fetchCustomerJobRequest()
and it doesn't print. Also, the reason why I have a question mark at the end of my var jobReuest: JobRequest?
is because I initiate it in my FindEmployeeJobRequestController
for the first time through the app, if that's correct too? Thank you in advance!
Database Reference Setup
JobRequest Model
struct JobRequest {
let uid: String
let fullname: String
let username: String
let address: String
let firstDateAndTimes: String
let secondDateAndTimes: String
let thirdDateAndTimes: String
let timeConstraints: String
let jobDescription: String
init(dictionary: [String : Any]) {
self.uid = dictionary["uid"] as? String ?? ""
self.fullname = dictionary["fullname"] as? String ?? ""
self.username = dictionary["username"] as? String ?? ""
self.address = dictionary["address"] as? String ?? ""
self.firstDateAndTimes = dictionary["firstDateAndTimes"] as? String ?? ""
self.secondDateAndTimes = dictionary["secondDateAndTimes"] as? String ?? ""
self.thirdDateAndTimes = dictionary["thirdDateAndTimes"] as? String ?? ""
self.timeConstraints = dictionary["timeConstraints"] as? String ?? ""
self.jobDescription = dictionary["jobDescription"] as? String ?? ""
}
}
Services API
struct CustomerService {
static func fetchCustomerJobRequest(completion: @escaping(JobRequest) -> Void) {
guard let uid = Auth.auth().currentUser?.uid else { return }
REF_CUSTOMERS.child(uid).child("job-request-details").childByAutoId().observeSingleEvent(of: .value) { snapshot in
guard let dictionary = snapshot.value as? [String : Any] else { return }
let jobRequest = JobRequest(dictionary: dictionary)
completion(jobRequest)
}
}
}
FindEmployeeJobRequestController
// MARK: - Properties
var jobRequest: JobRequest? {
didSet {
configure()
}
}
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
fetchCustomerJobRequest()
}
// MARK: - API
func fetchCustomerJobRequest() {
CustomerService.fetchCustomerJobRequest { jobRequest in
self.jobRequest = jobRequest
}
}
// MARK: - Helper Functions
fileprivate func configure() {
guard let jobRequest = jobRequest else { return }
let viewModel = JobRequestViewModel(jobRequest: jobRequest)
fullnameDetailsLabel.text = viewModel.fullname
usernameDetailsLabel.text = "@" viewModel.username
addressDetailsLabel.text = viewModel.address
firstDateAndTimeDetailsLabel.text = viewModel.firstDateAndTimes
secondDateAndTimeDetailsLabel.text = viewModel.secondDateAndTimes
thirdDateAndTimeDetailsLabel.text = viewModel.thirdDateAndTimes
timeConstraintsDetailsLabel.text = viewModel.timeConstraints
jobDescriptionDetailsLabel.text = viewModel.jobDescription
}
CodePudding user response:
This code doesn't do what you expect it to do:
REF_CUSTOMERS.child(uid).child("job-request-details").childByAutoId().observeSingleEvent(of: .value)
Calling childByAutoId()
it generates a new unique location, that you then call observeSingleEvent
on. But since you don't write anything to this location, there will never be any value for the listener to get.
So the snapshot.value
will be nil
in the callback, and in fact snapshot.exists()
will be false
.