mental
mental

Reputation: 83

Delete tableView cell and remove data from firebase

I'm working on study project of social network. Stuck on the stage of deleting user comments from Firebase database. To delete a specific comment I need to know the comment Id, but I do not understand how to access it. I'm really appreciate any help on this!

Example of Firebase database:

enter image description here

CommentViewController:

class CommentViewController: UIViewController {

@IBOutlet weak var sendButton: UIButton!
@IBOutlet weak var commentTextField: UITextField!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var constraintToBottom: NSLayoutConstraint!

var postId: String!
var comments = [Comment]()
var users = [User]()

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    title = "Comment"
    tableView.estimatedRowHeight = 77
    tableView.rowHeight = UITableView.automaticDimension
    empty()
    handleTextField()
    loadComments()
    
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    view.endEditing(true)
}


@objc func keyboardWillShow(_ notification: NSNotification) {
    let keyboardFrame = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
    UIView.animate(withDuration: 0.3) {
        self.constraintToBottom.constant = keyboardFrame!.height
        self.view.layoutIfNeeded()
    }
}

@objc func keyboardWillHide(_ notification: NSNotification) {
    UIView.animate(withDuration: 0.3) {
        self.constraintToBottom.constant = 0
        self.view.layoutIfNeeded()
    }
}

var comment: Comment?


func loadComments() {
    Api.Post_Comment.REF_POST_COMMENTS.child(self.postId).observe(.childAdded, with: {
        snapshot in
        Api.Comment.observeComments(withPostId: snapshot.key, completion: {
            comment in
            self.fetchUser(uid: comment.uid!, completed: {
                self.comments.append(comment)
                self.tableView.reloadData()
                
            })
        })
    })
}


func fetchUser(uid: String, completed: @escaping() -> Void ) {
    
    Api.User.observeUser(withId: uid, completion: {
        user in
        self.users.append(user)
        completed()
    })
}


func handleTextField() {
    commentTextField.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControl.Event.editingChanged)
}

@objc func textFieldDidChange() {
    if let commentText = commentTextField.text, !commentText.isEmpty {
        sendButton.setTitleColor(UIColor.black, for: UIControl.State.normal)
        sendButton.isEnabled = true
        return
    }
    sendButton.setTitleColor(UIColor.lightGray, for: UIControl.State.normal)
    sendButton.isEnabled = false
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.tabBarController?.tabBar.isHidden = true
}


override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.tabBarController?.tabBar.isHidden = false
}

@IBAction func sendButton_TouchUpInside(_ sender: Any) {
    let commentsReference = Api.Comment.REF_COMMENTS
    let newCommentId = commentsReference.childByAutoId().key!
    let newCommentReference = commentsReference.child(newCommentId)
    
    guard let currentUser = Api.User.CURRENT_USER else {
        return
    }
    let currentUserId = currentUser.uid
    newCommentReference.setValue(["uid": currentUserId, "commentText": commentTextField.text!], withCompletionBlock: {
        (error, ref) in
        if error != nil {
            ProgressHUD.showError(error!.localizedDescription)
            return
        }
        let postCommentRef = Api.Post_Comment.REF_POST_COMMENTS.child(self.postId).child(newCommentId)
        postCommentRef.setValue(true, withCompletionBlock: { (error, ref) in
            if error != nil {
                ProgressHUD.showError(error!.localizedDescription)
                return
            }
        })
        self.empty()
        self.view.endEditing(true)
    })
}


func empty() {
    self.commentTextField.text = ""
    sendButton.setTitleColor(UIColor.lightGray, for: UIControl.State.normal)
    sendButton.isEnabled = false
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "Comment_ProfileSegue" {
        let profileVC = segue.destination as! ProfileUserViewController
        let userId = sender as! String
        profileVC.userId = userId
    }
}



extension CommentViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return comments.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentTableViewCell
    let comment = comments[indexPath.row]
    let user = users[indexPath.row]
    cell.comment = comment
    cell.user = user
    cell.delegate = self
    return cell
}

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if (editingStyle == .delete) {
        

        
        
    }
}

CommentTableViewCell:

class CommentTableViewCell: UITableViewCell {
@IBOutlet weak var profileImageView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var commentLabel: UILabel!

var delegate: CommentTableViewCellDelegate?
var comment: Comment? {
    didSet {
        updateView()
    }
}


var user: User? {
    didSet {
        setupUserInfo()
    }
} 

func updateView() {
    commentLabel.text = comment?.commentText
}


func setupUserInfo() {
    nameLabel.text = user?.username
    if let photoUrlString = user?.profileImageUrl {
        let photoUrl = URL(string: photoUrlString)
        profileImageView.sd_setImage(with: photoUrl, placeholderImage: UIImage(named: "photo_placeholder"))
    }
}

override func awakeFromNib() {
    super.awakeFromNib()
    nameLabel.text = ""
    commentLabel.text = ""
    let tapGestureForNameLabel = UITapGestureRecognizer(target: self, action: #selector(self.nameLabel_TouchUpInside))
    nameLabel.addGestureRecognizer(tapGestureForNameLabel)
    nameLabel.isUserInteractionEnabled = true
}

@objc func nameLabel_TouchUpInside() {
    if let id = user?.id {
        delegate?.goToProfileUserVC(userId: id)
    }
}

override func prepareForReuse() {
    super.prepareForReuse()
    profileImageView.image = UIImage(named: "placeholderImg")
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

Comment Api

class CommentApi {
var REF_COMMENTS =  Database.database().reference().child("comments")

func observeComments(withPostId id: String, completion: @escaping (Comment) -> Void) {
    REF_COMMENTS.child(id).observeSingleEvent(of: .value, with: {
        snapshot in
        if let dict = snapshot.value as? [String: Any] {
            let newComment = Comment.transformComment(dict: dict, key: snapshot.key)
            completion(newComment)
        }
    })
}

func observeComment(withId id: String, completion: @escaping (Comment) -> Void) {
    REF_COMMENTS.child(id).observeSingleEvent(of: DataEventType.value, with: {
        snapshot in
        if let dict = snapshot.value as? [String: Any] {
            let comment = Comment.transformComment(dict: dict, key: snapshot.key)
            completion(comment)
        }
    })
}

Comment Model:

class Comment {
var commentText: String?
var uid: String?
var id: String?}

 extension Comment {
static func transformComment(dict: [String: Any], key: String) -> Comment {
    let comment = Comment()
    comment.id = key
    comment.commentText = dict["commentText"] as? String
    comment.uid = dict["uid"] as? String
    return comment
}

Upvotes: 0

Views: 171

Answers (1)

Jay
Jay

Reputation: 35648

Speaking at a high level, your tableView is backed by a dataSource, typically an array, which is the source for the content displayed in the tableView.

var userCommentArray = [UserComment]()

you should be loading data from Firebase and storing that data in the array as UserComment objects

class UserComment {
   var firebaseKey = ""
   var commentText = ""
   var uid = ""
}

the firebase_key property is the key to the node in Firebase, shown as -MH_xxxx in the screenshot and then the commentText and uid are is the child data of that node.

The indexes of the elements in the array match what's being shown in the tableView, so row0 matches the array index 0, row 1 matches the array index 1 etc.

When the user deletes row 1, you know that's index 1 in the array. read the object, get it's firebaseKey and then delete it from firebase, updating the array accordingly and then reloading your UI.

See my answer to your Other Question for details on that process.

Upvotes: 1

Related Questions