Mahdia Daqiq Mahdia Daqiq - 1 month ago 10
iOS Question

deleting a child from firebase when flagging a post

I have been trying to delete a post from firebase when the post gets more then 2 flags. I have tried a lot of ways and I cannot figure it out. I have some images attached help would be appreciated!
`

// 4
if poster.uid != User.current.uid {
let flagAction = UIAlertAction(title: "Report as Inappropriate", style: .default) { _ in
PostService.flag(post)

/// addedflag

let flaggedPostRef = Database.database().reference().child("flaggedPosts").child(postKey!)


// 3
var flaggedDict = ["text": post.textData,
"poster_uid": post.poster.uid,
"reporter_uid": User.current.uid]

// 4
flaggedPostRef.updateChildValues(flaggedDict)

// 5
let flagCountRef = flaggedPostRef.child("flag_count")
flagCountRef.runTransactionBlock({ (mutableData) -> TransactionResult in


let currentCount = mutableData.value as? Int ?? 0
mutableData.value = currentCount

if mutableData.value as! Int >= 1 {



let uid = FIRAuth.auth()!.poster.uid!.uid

// Remove the post from the DB
ref.child("posts").child(postKey).removeValue { error in
if error != nil {
print("error \(error)")
}
}
postKey?.removeVolue()
let timelinePostDict = ["poster_uid" : poster.uid]
var updatedData: [String : Any] = ["timeline/\(poster.uid)/\(postKey)" : timelinePostDict]

let postToBeDeleted = Database.database().reference().child("posts")
updatedData["timeline/\(poster.uid)/\(postKey)"] = timelinePostDict
updatedData["posts/\(poster.uid)/\(postKey)"] = postKey


print("Delete case: mutableData.value = \(mutableData.value)")

} else {
print("Case not met. Either not equal to 2 or not able to cast as Integer type. The value of the casted in is \(mutableData.value as? Int)")
}




mutableData.value = currentCount + 1


return TransactionResult.success(withValue: mutableData)
})


`the code for flaging Friebase

Answer Source

The .runTransactionBlock({.. gets triggered multiple times before the value is appended/updated at a particular node. What you need is an observer :-

Database.database().reference().child("flaggedPosts").observe(.childChanged, with: {(Snapshot) in

        // Every time a child dictionary in the flaggedPosts node
        // would change you will receive that dictionary in this block
        // be it any change in any of the values in that postKey
        // Check the flagCount value and perform the action requisite... 

        print(Snapshot.value ?? "No value retrieved")



        if let snapDict = Snapshot.value as? NSDictionary{

            let count = snapDict["count"] as! Int
            let postID = snapDict["postKey"] as! String
            let posterUID = snapDict["poster_uid"] as! String

            if count > 1{

                print(postID)

                // You will only be pushed into this block only if your count value
                // is greater than 1 i.e 2

                // Delete postID in your database

                Database.database().reference().child("posts/\(posterUID)/\(postID)").removeValue(completionBlock: {(Err, ref) in

                    // Handle the error you recieve while deleting 
                    // the flagged post


                })
            }
        }

    }, withCancel: {(Error) in

        // Handle the error recieved while making 
        // a call to firebase

    })

Given that this method uses an .observe(.childChanged.., this is an asynchronous active call whose observer is not removed from the network link. to your database which will get triggered every time your child is changed/updated...