I have some trouble doing the following:
What I want to achieve is to read from "Time report" and display the "user names" as "options" in the UIpickerView (in the "dropdown menu").
(The plan is to later be able to display the information in each of the "options" in the same view. Something like choosing a "User" in a app and having the users "stats" displayed.)
Any help would be great!
This is my code: Well for now, I dont really have code as everything i'v tried seems not to work. Last working code was:
func fetchUser()
{
ref = Database.database().reference() //Set the reference//
databaseHandle = ref?.child("Time report").observe(.childAdded, with: { (snapshot) in
print (snapshot)
})
}
My database looks like: (Login is the first node. Meaning its the node closest to the root - if that makes any sens.)
My Results Well, for now - I only get Fred, Kalle and Ivar printed, with all their information...
I've tried:
Used this video to aid in create a pickerView.
Here's how it's done. I am assuming you know how to populate a dataSource for your pickerView in general. If you need help with that, it would be best addressed as a separate question.
Assume we are using a structure like the one in the original question:
time_report
adam
gym
timestamp_0
From : "from_0",
To : "to_0"
timestamp_1
From : "from_1",
To : "to_1"
home : {
timestamp_0
From : "from_0",
To : "to_0"
work : {
timestamp_0
From : "from_0",
To : "to_0"
Notes:
1) best practice is to not use spaces in keys so I am using time_report
2) It's not clear if under each option (gym, home, work) there will be
multiple nodes so I included two under gym for demonstration purposes
3) I am using placeholders for timestamps from_0, to_0 etc but you get the idea.
4) This will handle any situation for options; they could be gym, home, work
or A, B, C or whatever the key names are.
5) Nothing is hard coded so as timestamps change, the code continues to work
Now to read the options (gym, home, work or whatever they may be) for the adam node here's the code.
let timeReportRef = self.ref.child("time_report")
let adamRef = timeReportRef.child("adam")
adamRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let snap = child as! DataSnapshot
let nodeKey = snap.key //will be gym, home, work
print(nodeKey)
//populate your dataSource Array here with the nodeKeys
//the following code could be used to populate a structure with additional
// info so when the user taps 'gym', we have already loaded the gym data
// and can populate another view controller with the details
for childTimes in snap.children { //the child nodes under gym, home, work
let timeSnap = childTimes as! DataSnapshot
let timeKey = timeSnap.key
let dict = timeSnap.value as! [String: Any]
let from = dict["From"] as! String
let to = dict["To"] as! String
print(" timestamp: \(timeKey)")
print(" from: \(from)")
print(" to: \(to)")
}
}
})
and the output
gym
timestamp: timestamp_0
from: from_0
to: to_0
timestamp: timestamp_1
from: from_1
to: to_1
home
timestamp: timestamp_0
from: from_0
to: to_0
work
timestamp: timestamp_0
from: from_0
to: to_0
The important bit here is that if you just want to add gym, home, work to your pickerView, you can omit the For loop. However. That loop demonstrates how to load additional data (timestamps) under gym, home and work.
There's a couple of directions to go from here. If you want to load the firebase data from Firebase when the user taps gym for example, you would get what the user tapped (gym) and you are in the adam section so it would be
let user = userSection //assume we are in the 'adam' section
let option = optionTapped //assume the user tapped gym
let userOptionRef = self.ref.child(user).child(option)
userOptionRef.observeSingleEvent(.value.... etc etc to read in that data.
Another option would be to read it all in at one time, as in the code I provided)\, and populate a class with that info. Then store the class in a dataSource array to be used in the picker.
class userStuff {
option = ""
data: DataSnapshot?
}
populate that class or stuct within the closure I presented and then store it in an array. Then in your pickerView, as it's being updated, get the userStuff class from the array for the row and read the option text. If the user then taps on row 0, 'gym' read the array, row 0, get the dataSnapshot and iterate over it to populate a sub view with the timestamp info.
Edit
Original question was changed and in response to a comment here:
let timeReportRef = self.ref.child("Time report")
timeReportRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let snap = child as! DataSnapshot
print(snap.key)
}
})
output will be
Fred
Ivar
Kalle