Reputation: 1412
I have Firebase generating random keys for my records in a Swift app. How do I go about retrieving that key if I want to change a specific record? In my example below, I'm marking a task complete but when I hit the button it doesn't work as intended because I am not referencing the particular task but to reference the task I need the randomly generated key.
func doneHit(cell:TaskCell) {
if let ip = tableView.indexPathForCell(cell) {
var task = tasksInSectionArray[ip.section][ip.row]
let tasksRef = ref.childByAppendingPath("tasks")
ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
let doneRef = tasksRef.childByAppendingPath("\(snapshot.key)/done")
if task.done == false {
task.done = true
cell.checkBox.image = UIImage(named: "checkedbox")
doneRef.setValue(task.done)
}
else {
task.done = false
cell.checkBox.image = UIImage(named: "uncheckedbox")
doneRef.setValue(task.done)
}
let completedByRef = tasksRef.childByAppendingPath("\(snapshot.key)/completedBy")
if task.done == true {
completedByRef.setValue(self.user)
cell.detailLabel.text = "Completed By: \(self.user)"
}
else {
completedByRef.setValue("")
cell.detailLabel.text = ""
}
})
}
}
My Firebase structure:
Update 1:
I have updated my code to get the IDs for all of the tasks but the functionality of updating the backend isn't working properly. It is only letting update the tasks created in the app. There are 150 tasks that I imported using the web Dashboard. Those are the ones I can't get to update.
func doneHit(cell:TaskCell) {
if let ip = tableView.indexPathForCell(cell) {
var task = tasksInSectionArray[ip.section][ip.row]
let tasksRef = ref.childByAppendingPath("tasks")
var taskID = ""
tasksRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
for task in snapshot.children {
let _tasks = task as! FDataSnapshot
let id = _tasks.key
print(id)
taskID = id
}
let doneRef = tasksRef.childByAppendingPath("\(taskID)/done")
if task.done == false {
task.done = true
cell.checkBox.image = UIImage(named: "checkedbox")
doneRef.setValue(task.done)
}
else {
task.done = false
cell.checkBox.image = UIImage(named: "uncheckedbox")
doneRef.setValue(task.done)
}
let completedByRef = tasksRef.childByAppendingPath("\(taskID)/completedBy")
if task.done == true {
completedByRef.setValue(self.user)
cell.detailLabel.text = "Completed By: \(self.user)"
}
else {
completedByRef.setValue("")
cell.detailLabel.text = ""
}
})
}
}
Upvotes: 8
Views: 11875
Reputation: 3090
An alternative to Ron's answer involves generating the key first and then using it to set value:
let autoId = databaseReference.childByAutoId().key
databaseReference.child(autoId).setValue(YOUR_VALUE)
Upvotes: 0
Reputation: 408
Following Tim's answer for Swift 3 and Firebase 4 I had to use the below
for task in snapshot.children {
guard let taskSnapshot = task as? DataSnapshot else {
continue
}
let id = taskSnapshot.key
Upvotes: 1
Reputation: 12562
tasksRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
for task in snapshot.children {
guard let taskSnapshot = task as? FDataSnapshot else {
continue
}
let id = task.key
// do other things
}
}
Upvotes: 5
Reputation: 16703
To create a randomly generated key you need to use childByAutoId()
(which I can't see in your example code).
This will return a Firebase reference you could use and which will return the key with it's .key
property
var post1Ref = ref.childByAutoId()
post1Ref.setValue(post1)
var postId = post1Ref.key
See documentation here
Upvotes: 27