Ad

Firebase Query Not Returning Any Data

My datamodel looks as follows :

allcomments
|__$comment_id_5
         |__post_id: <post_id_5>



uid
|
|__activity
     |__comments
            |__$random_activity_id
                       |__post_id : <post_id_5> //ref to post_id_5 in allcomments
                       |__comment_id : <comment_id_5> // ref to comment_id_5 in allcomments 

My Goal: To check if the user with uid has commented on the post or not. If that person has, then I he can proceed further else he'll be shown something else on the screen. On trying the following query, I am able to only get the callback when a snapshot exists and not otherwise.

FBDataservice.ds.child("allcomments").queryOrdered(byChild: "post_id").queryEqual(toValue: "post_id_5").observeSingleEvent(of: .ChildAdded) { (snapshot) in
        if let data = snapshot.value as? DataDict {
            let comment = Comment(comId: snapshot.key , comData: data)
            self.checkUserHasResponded(completion: { (hasResponded) in
                if !hasResponded {
                    // Never returns it there is nothng
                    print("You gotta respond first")
                } else {
                    //this part does work
                    print("Welcome to seeing everything")
                }
            })
        }
    }


func checkUserHasResponded(completion: @escaping (Bool) -> ()) {
    FBDataservice.ds.REF_USERS.child(uid).child("activity/comments").queryOrdered(byChild: "post_id").queryEqual(toValue: "post_id_5").observeSingleEvent(of: .value) { (snapshot) in
        snapshot.exists() ? completion(true) : completion(false)
    }
}

I even tried tweaking the architecture this way and query it differently, still nothing work and the program behaves in the same exact way as incase of above.

uid
|
|__activity
     |__comments
            |__post_id_5 : comment_id_5

and ran this query:

func checkUserHasResponded(completion: @escaping (Bool) -> ()) {
    FBDataservice.ds.REF_USERS.child(uid).child("activity/comments").observeSingleEvent(of: .value) { (snapshot) in
        snapshot.hasChild("post_id_5") ? completion(true) : completion(false)
    }
}

I tried changing .childAdded to .value. It gives the same exact result. Tried changing .observeSingleEvent(of:) to .observe() as well. But nothing helps. I am not sure what exactly is wrong. Check plenty of answers here, none helped. What exactly am I over looking. Thanks for the help.

Ad

Answer

Use .value instead of .childAdded, that way it the closure is called whether or not the snapshot exists, Just a quick test shows it works.

func checkUserHasResponded() {
    let uid = "uid_0"
    let commentsRef = dbRef.child(uid).child("activity").child("comments")
    commentsRef.queryOrdered(byChild: "post_id")
               .queryEqual(toValue: "post_5")
               .observeSingleEvent(of: .value) { snapshot in
        if snapshot.exists() {
            print("post exists")
        } else {
            print("post not found")
        }
    }
}

If your structure does not contain a post_id child value that exists then the output is

post not found

So this answer applies to the updated question. The code in the closure will not run if the node you're querying for does not exist because the query is using .childAdded

FBDataservice.ds.child("allcomments").queryOrdered(byChild: "post_id")
                                 .queryEqual(toValue: "post_id_5")
                                 .observeSingleEvent(of: .childAdded) { (snapshot) in

If that's changed to .value, it returns and the code in the closure runs if the node exists. Keeping in mind that you'll want to use

snapshot.exists()

with that as it will be nil if it doesn't.

Ad
source: stackoverflow.com
Ad