Firstly, here are some methods you can add to your User class for convenience.
static var ref: DatabaseReference {
return Database.database().reference(withPath: "users")
}
var ref: DatabaseReference {
return User.ref.child(snapshot.key)
}
As well as an extension for DataSnapshot to make mapping them to User easier.
extension DataSnapshot {
var childrenSnapshots: [DataSnapshot] {
return children.allObjects as? [DataSnapshot] ?? []
}
}
Lastly, we can refactor your fetchAllUsers function to utilise the helpers.
func fetchAllUsers(completion: @escaping ([User]) -> ()) {
User.ref.observe(.value, with: { (snapshot) in
completion(snapshot.childrenSnapshots.map { User(snapshot: $0) })
}) { (error) in
print(error.localizedDescription)
}
}
Now everything is easier to read, let's consider your aim - you want to retrieve the id of a selected user from a table view. The id of a user is essentially the key of the user snapshot, which we use to instantiate the User class.
Your User.init function should use the snapshot to populate the class properties, and so you could also use this opportunity to retrieve the key of the snapshot and set a property on the User class to store it. There's a nicer way.
// MARK: Properties
var snapshot: DataSnapshot?
var key: String? {
return snapshot?.key
}
...
// MARK: Lifecycle
init(snapshot: DataSnapshot) {
self.snapshot = snapshot
...
}
When you initialise a User with a snapshot, you can store the snapshot for later and use a computed property to retrieve the key. So as long as you are storing your users in an array, you can use the indexPath of the cell selected to find the selected user in the array.
var users: [Users]?
...
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if users?.indices.contains(indexPath.row) == true {
performSegue(withIdentifier: "showUser", sender: users?[indexPath.row])
}
}
...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch (segue.destination, sender) {
case (let controller as ViewController, let user as User):
controller.user = space
default:
break
}
}
And once you have your user, you have your key. You will need to perform a segue once a cell is selected - I like to use the sender argument to pass anything of relevance to the segue. For example, you can pass the selected User object and set it in the destination controller.
User