Reputation: 47
I have this function that is supposed to fetch data from a comments node
from firebase. I want to implement pagination to not load 100+ comments at once. Everything seems to be working but my code seems to be failing at casting the snapchat.value
to a Dictionary
func fetchComments(){
messagesRef = Database.database().reference().child("Comments").child(eventKey)
var query = messagesRef?.queryOrderedByKey()
if comments.count > 0 {
let value = comments.last?.commentID
query = query?.queryStarting(atValue: value)
}
query?.queryLimited(toFirst: 2).observe(.childAdded, with: { (snapshot) in
var allObjects = snapshot.children.allObjects as? [DataSnapshot]
allObjects?.forEach({ (snapshot) in
// print out snapshot and it isn't empty
print(snapshot.value) // here it keeps going into the else statement even though snapshot.value clearly exist.
guard let commentDictionary = snapshot.value as? [String:Any] else{
return
}
print(commentDictionary)
})
}) { (err) in
print("Failed to observe comments")
}
}
My question is can anyone take a look at this and maybe see where I went wrong? My code looks fine to me and I can't see what's is wrong.
My tree looks like this
"Comments" : {
"CCDS" : {
"-KrrsXkj6FznzRD0-Xzs" : {
"content" : "Shawn",
"profileImageURL" : "https://firebasestorage.googleapis.com/v0/b/eventful-3d558.appspot.com/o/profile_images%2FBC868F8F-E9EC-4B9D-A248-DD2187BC140C.PNG?alt=media&token=fb14700c-2b05-4077-b45c-afd3de705801",
"timestamp" : 1.503102381340935E9,
"uid" : "oxgjbrhingbf7vbaHpflhw6G7tB2"
}
},
"MIA" : {
"-Krghz9d5_CPjkmdffef" : {
"content" : "22",
"profileImageURL" : "https://firebasestorage.googleapis.com/v0/b/eventful-3d558.appspot.com/o/profile_images%2FF50F6915-DEAB-4A5B-B1AB-CABC1E349148.PNG?alt=media&token=4eb7c708-ec87-45bf-952d-0bd410faee50",
"timestamp" : 1.502915064803007E9,
"uid" : "oxgjbrhingbf7vbaHpflhw6G7tB2"
},
"-KrpoEnNYsmRZ5guORUj" : {
"content" : "23",
"profileImageURL" : "https://firebasestorage.googleapis.com/v0/b/eventful-3d558.appspot.com/o/profile_images%2FBC868F8F-E9EC-4B9D-A248-DD2187BC140C.PNG?alt=media&token=fb14700c-2b05-4077-b45c-afd3de705801",
"timestamp" : 1.503067700479352E9,
"uid" : "oxgjbrhingbf7vbaHpflhw6G7tB2"
}
}
}
Based off my code it bypasses the key and goes straight to the children. For example if pass in MIA it should go to MIA and grab the key corresponding to each comment "-KrrsXkj6FznzRD0-Xzs" and "-KrpoEnNYsmRZ5guORUj" but it is returning everything under that unique ID instead. Which is a problem
Upvotes: 1
Views: 719
Reputation: 598740
The code in your callback seems to assume that you get called with a collection of comments. To get such a collection you need to observe the .value
event. When you observe the .value
event, you callback gets invoked with a single snapshot
that contains all the nodes matching the query:
query?.queryLimited(toFirst: 2).observe(.value, with: { (snapshot) in
var allObjects = snapshot.children.allObjects as? [DataSnapshot]
allObjects?.forEach({ (snapshot) in
print(snapshot.key)
print(snapshot.value)
guard let commentDictionary = snapshot.value as? [String:Any] else{
return
}
print(commentDictionary)
})
}) { (err) in
print("Failed to observe comments")
}
When you observe .childAdded
, your callback instead gets called for every individual node matching the query. That means you need to get rid of a loop in your code:
query?.queryLimited(toFirst: 2).observe(.childAdded, with: { (snapshot) in
print(snapshot.key)
print(snapshot.value)
guard let commentDictionary = snapshot.value as? [String:Any] else{
return
}
print(commentDictionary)
}) { (err) in
print("Failed to observe comments")
}
Upvotes: 2