В вопросе много кода, а иногда проще, тем лучше.Итак, давайте возьмем класс Post, загрузим сообщения, получим имя пользователя и сохраним его в массиве.Затем по завершении сортируйте и распечатывайте сообщения в обратном хронологическом порядке.
Класс для хранения данных записи и имени пользователя
class PostClass {
var post = ""
var timestamp: Int! //using an int for simplicity in this answer
var user_name = ""
init(aPost: String, aUserName: String, aTimestamp: Int) {
self.post = aPost
self.user_name = aUserName
self.timestamp = aTimestamp
}
}
Обратите внимание, что если мы хотим, чтобы оба сообщенияданные и пользовательские данные, мы могли бы сделать это
class PostUserClass {
var post: PostClass()
var user: UserClass()
}
, но мы оставим это простым для этого ответа.
Затем массив для хранения сообщений
var postArray = [PostClass]()
и, наконец, код для загрузки всех постов, получения связанного имени пользователя (или объекта пользователя в полном примере).
let postsRef = self.ref.child("posts")
let usersRef = self.ref.child("users")
postsRef.observeSingleEvent(of: .value, with: { snapshot in
let lastSnapIndex = snapshot.childrenCount
var index = 0
for child in snapshot.children {
let childSnap = child as! DataSnapshot
let uid = childSnap.childSnapshot(forPath: "uid").value as! String
let post = childSnap.childSnapshot(forPath: "post").value as! String
let timestamp = childSnap.childSnapshot(forPath: "timestamp").value as! Int
let thisUserRef = usersRef.child(uid)
thisUserRef.observeSingleEvent(of: .value, with: { userSnap in
index += 1
//for simplicity, I am grabbing only the user name from the user
// data. You could just as easily create a user object and
// populate it with user data and store that in PostClass
// that would tie a user to a post as in the PostUserClass shown above
let userName = userSnap.childSnapshot(forPath: "Name").value as! String
let aPost = PostClass(aPost: post, aUserName: userName, aTimestamp: timestamp)
self.postArray.append(aPost) //or use self.postUserArray to store
// PostUserClass objects in an array.
if index == lastSnapIndex {
self.sortArrayAndDisplay() //or reload your tableView
}
})
}
})
, а затем маленькая функция сортировки и печати в консоль
func sortArrayAndDisplay() {
self.postArray.sort(by: {$0.timestamp > $1.timestamp})
for post in postArray {
print(post.user_name, post.post, post.timestamp)
}
}
Обратите внимание, что Firebase является асинхронным, поэтому перед сортировкой / печатью мы должны знать, что мы загрузили все данные.Это обрабатывается с помощью lastSnapIndex и индекса.Индекс увеличивается только после того, как каждый пользователь загружен, и когда все сообщения и пользователи загружены, мы затем сортируем и печатаем по мере завершения данных.
В этом примере избегаются грязные обратные вызовы и обработчики завершения, которые могут вносить вкладк вопросу в вопросе - этот фрагмент кода является подозрительным и, вероятно, его следует избегать из-за асинхронной природы Firebase;Функция сортировки будет вызываться задолго до загрузки всех пользователей.
UserApi.shared.observeUserToPost(uid: userUid) { (user) in
self.postUser.append(user)
}
self.postUser.sort(by: {$0.postDate! > $1.postDate!})
* добавьте проверку ошибок.