In my App I want to show a feed which generates a tableView depending on which groups the user subscribed. In the background two Firebase request are done and then converted to a tableView. My Code shows the content correct. But there are two issues. The order is wrong. It should be 4->3->2->1 (based on timestamp) and right now it is random. Also if I click on a comment the didSeleceRowAt works totally wrong. How can I manage to put the result in the same tableView correctly?
func datenBankAbfrage() {
ref = Database.database().reference().child("placeID/h77e24d95a5479ed7588")
ref.queryOrdered(byChild: "userTime").queryLimited(toLast: 10).observe(
DataEventType.value,
with: { (snapshot) in
self.ref = Database.database().reference().child(
"placeID/vh-b83b6e4475e04e3fbaa647d23b")
self.ref.queryOrdered(byChild: "userTime").queryLimited(toLast: 10).observe(
DataEventType.value,
with: { (snapshot2) in
for video in snapshot.children.allObjects as! [DataSnapshot] {
let Object1 = video.value as? [String: AnyObject]
let userName = Object1?["userName"]
let userGroup = Object1?["userGroup"]
let userComment = Object1?["userComment"]
let userTime = Object1?["userTime"]
let userLikes = Object1?["userLikes"]
let commentId = Object1?["commentId"]
ViewComments.commentIDNew = commentId as! String
let video = importComment(
userName: userName as! String, userGroup: userGroup as! String,
userComment: userComment as! String, userTime: userTime as! Int,
userLikes: userLikes as! Int, commentId: commentId as! String)
self.table.insert(video, at: 0)
// self.table.append(video)
self.tableView.reloadData()
}
for video in snapshot2.children.allObjects as! [DataSnapshot] {
let Object2 = video.value as? [String: AnyObject]
let userName = Object2?["userName"]
let userGroup = Object2?["userGroup"]
let userComment = Object2?["userComment"]
let userTime = Object2?["userTime"]
let userLikes = Object2?["userLikes"]
let commentId = Object2?["commentId"]
ViewComments.commentIDNew = commentId as! String
let video2 = importComment(
userName: userName as! String, userGroup: userGroup as! String,
userComment: userComment as! String, userTime: userTime as! Int,
userLikes: userLikes as! Int, commentId: commentId as! String)
self.table.insert(video2, at: 0)
// self.table.append(video)
self.tableView.reloadData()
}
})
})
}
class importComment {
var userName: String?
var userID: String?
var userGroup: String?
var userComment: String?
var userTime: Int?
var userLikes: Int?
var commentId: String?
init(
userName: String?, userGroup: String?, userComment: String?, userTime: Int?,
userLikes: Int?, commentId: String?
) {
self.userName = userName
self.userGroup = userGroup
self.userComment = userComment
self.userTime = userTime
self.userLikes = userLikes
self.commentId = commentId
}
}
No need to fetch data in Loops. As you're calling asynchronous functions in a loop, there is no guarantee of order.
You should use DispatchGroup
. Here is how execution will go:
DispatchGroup
instance.SnapShot-1
Fetch request to the Dispatch group.SnapShot-2
Fetch request to the Dispatch group.Notify()
will only be called after both the tasks has been completed. So you should prepare your data there.Here is an example implementation:
func datenBankAbfrage() {
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
ref = Database.database().reference().child("placeID/h77e24d95a5479ed7588")
ref.queryOrdered(byChild: "userTime").queryLimited(toLast: 10).observe(
DataEventType.value,
with: { (snapshot) in
for video in snapshot.children.allObjects as! [DataSnapshot] {
let Object1 = video.value as? [String: AnyObject]
let userName = Object1?["userName"]
let userGroup = Object1?["userGroup"]
let userComment = Object1?["userComment"]
let userTime = Object1?["userTime"]
let userLikes = Object1?["userLikes"]
let commentId = Object1?["commentId"]
ViewComments.commentIDNew = commentId as! String
let video = importComment(
userName: userName as! String, userGroup: userGroup as! String,
userComment: userComment as! String, userTime: userTime as! Int,
userLikes: userLikes as! Int, commentId: commentId as! String)
self.table.append(video)
}
dispatchGroup.leave()
})
dispatchGroup.enter()
self.ref = Database.database().reference().child(
"placeID/vh-b83b6e4475e04e3fbaa647d23b")
self.ref.queryOrdered(byChild: "userTime").queryLimited(toLast: 10).observe(
DataEventType.value,
with: { (snapshot2) in
for video in snapshot2.children.allObjects as! [DataSnapshot] {
let Object2 = video.value as? [String: AnyObject]
let userName = Object2?["userName"]
let userGroup = Object2?["userGroup"]
let userComment = Object2?["userComment"]
let userTime = Object2?["userTime"]
let userLikes = Object2?["userLikes"]
let commentId = Object2?["commentId"]
ViewComments.commentIDNew = commentId as! String
let video2 = importComment(
userName: userName as! String, userGroup: userGroup as! String,
userComment: userComment as! String, userTime: userTime as! Int,
userLikes: userLikes as! Int, commentId: commentId as! String)
self.table.append(video)
}
dispatchGroup.leave()
})
dispatchGroup.notify(queue: .main) {
// This is invoked when all the tasks in the group is completed.
self.prepareDatasource()
}
}
func prepareDatasource() {
self.table.sort(by: { $0.userTime ?? 0 > $1.userTime ?? 1}) // Sorting data
DispatchQueue.main.async {
self.tableView.reloadData()
}
}