Reputation: 311
I am trying to return the count of posts for a specific user where a field contains a certain value. The structure I am using in Firebase is here:
{
"posts" : {
"-Lyzpsb1hH4LUPvcXE3H" : {
"beverageCategory" : "Beer",
"beverageName" : "Dortmunder",
"beveragePrice" : "3.99",
"beverageRating" : 3,
"beverageType" : "Lager",
"imageUrl" : "https://firebasestorage.googleapis.com/v0/b/socialspirit-37cae.appspot.com/o/post-pics%2F3C23E923-A3BD-4393-B3EF-8F939D8B08B8?alt=media&token=ac80cb98-f2a1-4197-b328-2a69a2ac1fd1",
"wineVintage" : ""
}
},
"user" : "sdkjvksdjf",
"users" : {
"0hyN8N2klJWqPi2lkRqNK3vg7z63" : {
"posts" : {
"-Ly6ciYHm7v5JFy1VmVY" : true,
"-Ly6cyLukI6aRRki5yna" : true
},
"provider" : "Firebase"
},
"26OUuaRZEVWUmkLJp13LzirGbs13" : {
"posts" : {
"-Ly6fGmQEMZz3c-azMnJ" : true
},
"provider" : "Firebase"
},
"5r6FulsvIRap7pLK5D3zV8qyPVv1" : {
"provider" : "Firebase"
},
"gQpktBMh97hTqiysHBwvVLZl70y1" : {
"posts" : {
"-Lyzpsb1hH4LUPvcXE3H" : true,
"-LyzqFgvmrBgdsgKSt_5" : true,
"-Lz-fIMDal00ex3_viQo" : true,
"-Lz-lXsSBqKlcf8hBext" : true,
"-Lz2eNLfk1PFEVkEgmwa" : true,
"-Lz2etF0UqFqLkdGOR13" : true,
"-Lz2fGUi0qzJtniNr5LX" : true,
"-Lz2gP5c47yHDO2g0ljr" : true,
"-Lz2gdhfedZfTtzjP2ee" : true,
"-Lz2gllC3caXgPf2VAPU" : true,
"-Lz2hH8FbNmBEOLcHCJz" : true,
"-Lz2jzkXuEZ3Cfe96eGW" : true,
"-Lz3RvuW4fMXarhW7vLv" : true,
"-Lz3S8YA0vgk4ZrjL_Kk" : true
},
"provider" : "Firebase"
}
}
}
I am using the following code to get the count of records that have a beverageCategory of "Beer".
DataService.ds.REF_USERS.child("\(uid)").child("posts").child("beverageCategory")
.queryOrderedByValue().queryEqual(toValue: "Beer")
.observe(DataEventType.value, with: { (snapshot) in
print("SNAP - \(snapshot.childrenCount)")
})
The childrenCount
returns 0
, however. Any idea what I'm doing wrong here? Thanks!
EDIT: I added the JSON for the data structure and I think I left an important detail out. The data structure actually has users
that have posts
and the associated postid
that links back to posts
. I think what I have to do is first find the user's posts and then of those posts get a total count for each category. I'm guessing that is slightly different than the methods I tried. Any ideas on that?
EDIT 2: So my issues is that users
and posts
are in different structures. I need to find all of the user's posts
and iterate through them to see if what the beverageCategory
is. I have done that with the following code. The issue with the code below is that the count is doubled when I add a post
and then open the menu. But when I exit the menu and re-open the count is correct. Why is it double-counting?
func myFirebaseNetworkDataRequest(finished: @escaping () -> Void) {
beerCountArray.removeAll()
wineCountArray.removeAll()
liquorCountArray.removeAll()
print("BEER ARRAY \(beerCountArray.count)")
guard let uid = Auth.auth().currentUser?.uid else {
return
}
let newPost = DataService.ds.REF_USERS.child("\(uid)").child("posts")
newPost.observe(.value, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
//print("SNAPSHOT - \(snapshot)")
for snap in snapshot {
let postData = DataService.ds.REF_POSTS.child(snap.key)
//print("SNAP KEY - \(snap.key)")
let bevCat = DataService.ds.REF_POSTS.child(snap.key).child("beverageCategory")
//print("BEV CAT - \(bevCat)")
postData.observe(.value, with: { (snapshot) in
if let postDict = snapshot.value as? Dictionary<String, AnyObject> {
let key = snapshot.key
let post = Post(postKey: key, postData: postDict)
//print("POST DICT - \(String(describing: postDict["beverageCategory"]!))")
if postDict["beverageCategory"]! as! String == "Beer" {
self.beerCountArray.append(1)
//print("BEER ARRAY LOOP - \(self.beerCountArray)")
}
if postDict["beverageCategory"]! as! String == "Wine"{
self.wineCountArray.append(1)
}
if postDict["beverageCategory"]! as! String == "Liquor" {
self.liquorCountArray.append(1)
}
//self.posts.append(post)
}
finished()
})
}
}
})
}
And...
override func viewDidLoad() {
super.viewDidLoad()
beerCountArray.removeAll()
wineCountArray.removeAll()
liquorCountArray.removeAll()
myFirebaseNetworkDataRequest {
//print("BEER ARRAY - \(self.beerCountArray.count)")
self.beerCount.text = String(self.beerCountArray.count)
self.liquorCount.text = String(self.liquorCountArray.count)
self.wineCount.text = String(self.wineCountArray.count)
}
}
Upvotes: 0
Views: 213
Reputation: 598797
Your query is not correct. Since you're trying to filter on a child property of each node under posts
, you should call queryOrdered(byChild:)
.
So:
DataService.ds.REF_USERS.child("posts")
.queryOrdered(byChild: "beverageCategory")
.queryEqual(toValue: "Beer")
.observe(DataEventType.value, with: { (snapshot) in
print("SNAP - \(snapshot.childrenCount)")
})
Also see the Firebase documentation on ordering and filtering data.
Upvotes: 1