Reputation:
I have multiple posts and each post have it's own comments. I want to query all posts, ordered by their time stamps. I tried:
let query = Firebase(url: path)
let query.queryOrderedByChild("commentDate").observeEventType(.ChildAdded)
{ (queryResponse, cancelBlock) { ....
"commentDate" are integers on server. At this query I get only the first object
let query = Firebase(url: path)
query.queryOrderedByChild("commentDate").queryLimitedToFirst(100).observeEventType(.ChildAdded) { (queryResponse, cancelBlock) { ...
I get only the first object as well... The single solution I have at the moment is to query all :
query.queryOrderedByChild("commentDate").observeEventType(.Value) { (queryResponse, cancelBlock) in ...
But using this I must sort the array before showing to user.
Any ideas how can I do to get them sorted on server?
Edit Representation of firebase data:
{
"-KGRZmSIDXz5hHkelthQ" : {
"something1" : "783151",
"something2" : "21",
"something3" : "wjeicisje ejej",
"comments" : "",
},
"-KGRa5skGzA1GAG09Lno" : {
"something1" : "783151",
"something2" : "21",
"something3" : "wjeicisje ejej",
"comments" : "",
},
"-KGVr-tti1zr1M1QLlHL" : {
"something1" : "783151",
"something2" : "21",
"something3" : "wjeicisje ejej",
"comments" : {
"-KGX1_rFSBLmQJ7QzCRc" : {
"commentBody" : "something",
"commentDate" : 1.461933727259896E9,
"commentOwnerImageView" : "something",
"commentOwnerName" : "something"
},
"-KGX1r5Lnhv9YbQre6as" : {
"commentBody" : "something",
"commentDate" : 1.461933797884702E9,
"commentOwnerImageView" : "something",
"commentOwnerName" : "something"
},
"-KGXVGKA0SYm-vRs6zsv" : {
"commentBody" : "something",
"commentDate" : 1.461941507496439E9,
"commentOwnerImageView" : "something",
"commentOwnerName" : "something"
},
},
}
}
Upvotes: 0
Views: 1712
Reputation: 35677
Your data structure looks fine, so a simple query will return the results you want
let commentsRef = ref.childByAppendingPath("-KGVr-tti1zr1M1QLlHL/comments")
commentsRef.queryOrderedByChild("commentDate").observeEventType(.ChildAdded, withBlock: {
snapshot in
let nodeData = snapshot.value
print(nodeData!)
})
The above will return each child node, one at a time in the proper order.
If you have a small amount of nodes, you can just read them in at one time and iterate over the snapshot.children like this
usersRef.queryOrderedByChild("commentDate").observeEventType(.Value, withBlock: {
snapshot in
for child in snapshot.children {
print(child)
}
})
Both of the above will print out each comment node ordered by commentDate
The above will work only if you are interested in retrieving the comments within each post. If not, you'll need to change your Firebase structure and move the comments to separate node, like this
posts
post_01
post_02
etc
and a separate comments node that's refers to the post the comment belongs to. Since you want to query for say the comments for post_02, and want them ordered by commentDate, combine the post number and date into a single child.
comments
"-KGX1_rFSBLmQJ7QzCRc" : {
"for_post_and_commentDate": "post_02_1.461933727259896E9",
"commentBody" : "something",
"commentOwnerImageView" : "something",
"commentOwnerName" : "something"
},
"-KGX1r5Lnhv9YbQre6as" : {
"for_post_and_commentDate": "post_02_1.461933797884702E9",
"commentBody" : "something",
"commentOwnerImageView" : "something",
"commentOwnerName" : "something"
},
and then modify the query
usersRef.queryOrderedByChild("for_post_and_commentDate")
queryStartingAtValue("post_02_0").queryEndingAtValue("post_02_xxx").observeEventType(.Value, withBlock: {
You'll have to figure out your commentDate format as it would be easier to craft starting and ending timestamps if they were stored: 20160430100621 as a yyyymmddhhmmss format, then your timestamps could be queried like this:
starting: post_02_0
ending: post_02_99999999999999
This also gives you the flexibility to query for comments for post_02 that happened yesterday, or last week.
Upvotes: 1
Reputation: 600130
Firebase can query nested children if you know the entire path (so something like dimensions/length
). It cannot handle dynamic elements in that path under each child (like your $commentid/commentDate
).
The only way to get this working is to pull the necessary data up to a level where you can query it. For example, if you keep track of the lastCommentDate
for each blog post:
{
"-KGRZmSIDXz5hHkelthQ" : {
"something1" : "783151",
"something2" : "21",
"something3" : "wjeicisje ejej",
"comments" : "",
},
"-KGRa5skGzA1GAG09Lno" : {
"something1" : "783151",
"something2" : "21",
"something3" : "wjeicisje ejej",
"comments" : "",
},
"-KGVr-tti1zr1M1QLlHL" : {
"something1" : "783151",
"something2" : "21",
"something3" : "wjeicisje ejej",
"firstCommentDate": 1.461933727259896E9,
"lastCommentDate": 1.461941507496439E9,
"comments" : {
"-KGX1_rFSBLmQJ7QzCRc" : {
"commentBody" : "something",
"commentDate" : 1.461933727259896E9,
"commentOwnerImageView" : "something",
"commentOwnerName" : "something"
},
"-KGX1r5Lnhv9YbQre6as" : {
"commentBody" : "something",
"commentDate" : 1.461933797884702E9,
"commentOwnerImageView" : "something",
"commentOwnerName" : "something"
},
"-KGXVGKA0SYm-vRs6zsv" : {
"commentBody" : "something",
"commentDate" : 1.461941507496439E9,
"commentOwnerImageView" : "something",
"commentOwnerName" : "something"
},
},
}
}
With this structure you can query blog posts by their last comment date:
ref.orderByChild('lastCommentDate').limitToLast(10).on(...
Upvotes: 1