I'm trying to delete items from a Firebase database when user swipes to delete on the UITableView.
I'm also using the nifty showActivityIndicator and hideActivityIndicator functions from https://github.com/erangaeb/dev-notes/blob/master/swift/ViewControllerUtils.swift in order to easily show and hide the activity indicator.
I can see both the database record as well as the JPG file properly deleted from Firebase when the following code is run.
But the problem is that the activity indicator never disappears from the screen, and the UITableView does not refresh.
In fact, the
print("Stopping activity indicator")
and
print("Reloading table view")
do not even run.
What am I doing wrong?
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let alert = UIAlertController(title: "Delete Task", message: "Do you want to delete this task?", preferredStyle: .alert)
let confirmAction = UIAlertAction(title:"OK", style: .default) { action in
// Show activity indicator
ViewControllerUtils().showActivityIndicator(uiView: self.view)
// Retrieve Firebase reference to delete
let repairItem = self.repairItems[indexPath.row]
let storage = Storage.storage()
let storageRef = storage.reference()
let imageRef = storageRef.child(repairItem.imageRef)
// Delete the item from Firebase
repairItem.ref?.removeValue(completionBlock: {(error, ref) in
if let error = error {
print("Problem deleting item")
} else {
print("Item deleted successfully")
}
})
// Delete the photo
imageRef.delete { error in
if let error = error {
print("Problem deleting photo")
} else {
print("Photo deleted successfully")
}
}
print("Stopping activity indicator")
// Stop the activity indicator
ViewControllerUtils().hideActivityIndicator(uiView: self.view)
print("Reloading table view")
// Reloading table view
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default)
alert.addAction(confirmAction)
alert.addAction(cancelAction)
present(alert, animated: true, completion: nil)
}
}
Still not sure why the code below the Firebase removeValue and delete functions aren't running, but I managed to figure out a workaround.
Turns out that the code doesn't work only when I'm deleting the last remaining record on the table, after which the entire Firebase node is removed.
So I've added an observer to forcefully reload the table when this happens.
Under viewDidLoad(), I added the following lines:
override func viewDidLoad() {
super.viewDidLoad()
// ... other preceding lines of code
// Forcefully trigger a TableView refresh in case the Firebase node is empty
refItems.observe(.value, with: { snapshot in
if snapshot.exists() {
print("Found the Firebase node")
} else {
print("Firebase node doesn't exist")
self.tableView.reloadData()
}
})
// ...other following lines of code
}
When it comes to keeping a tableView and Firebase synchronized, there are two main options:
1) When removing a node from Firebase, manually remove it from the tableView datasource when removing it from Firebase. No observer needed.
2) Attach a remove event observer to Firebase so when a node is removed, your App will receive an event of which node it was, and remove it.
Here's an example; I am leaving the tableView code out for the sake of brevity.
Suppose we have a tableView that displays users. The tableView has a dataSource of usersArray which contain UserClass objects.
Given a Firebase structure
users
user_0
name: "Frank"
user_2
name: "Bill"
user_3
name: "Hugh"
We add three observers to the users node, childAdded, childChanged, childRemoved
class UserClass {
var key = ""
}
var usersArray = [UserClass]()
let usersRef = self.ref.child("users")
usersRef.observe(.childAdded, with: { snapshot in
let user = UserClass()
user.key = snapshot.key
self.usersArray.append(user)
self.tableView.reloadData()
})
usersRef.observe(.childChanged, with: { snapshot in
if let index = self.usersArray.index(where: {$0.key == snapshot.key}) {
//update it in the array via the index
self.tableView.reloadData()
} else {
//item not found
}
})
usersRef.observe(.childRemoved, with: { snapshot in
if let index = self.usersArray.index(where: {$0.key == snapshot.key}) {
self.usersArray.remove(at: index) //remove it from the array via the index
self.tableView.reloadUI()
} else {
item not found
}
})
If a user is added, the .childAdded observer receives the new user so it can be appended to the array.
If a user is changed, the .childChanged observer receives the changed user. Grab the key, which would typically be the uid, locate it in the array and update the properties.
If a user is removed, the .childRemoved observer receives the removed user. Grab the key, locate it in the array and remove it.
In each case, reload the tableView after the change to the dataSource.
you need to write code inside of block as below :
imageRef.delete { error in
if let error = error {
print("Problem deleting photo")
} else {
print("Photo deleted successfully")
ViewControllerUtils().hideActivityIndicator(uiView: self.view)
print("Reloading table view")
// Reloading table view
self.tableView.reloadData()
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.