Этот ответ основан на данных в вопросе и последующих комментариях.
Денормализация данных является стандартной практикой в базах данных NoSQL, но в этом случае рассматриваемая структура может быть более сложной, чем необходимо.
Вот вопрос
Учитывая серию постов, где у каждого поста есть комментарии, как вы загружаете
комментарии к каждому сообщению для отображения в табличном представлении.
Я собираюсь работать в обратном направлении от предложенной структуры
posts
post_0 //created with .childByAutoId
creator_uid: "the uid of whoever created this post"
post_title: "My post about posting"
comments
post_0 //ties back to the key of the post in the posts node
comment_0 //created with .childByAutoId
comment_by_uid: "whoever created this comment"
comment_text: "comment about this post"
comment_1
comment_by_uid: "whoever created this comment"
comment_text: "comment about this post"
Эта структура отделяет комментарии от поста, на который они ссылаются. В узле комментариев ключом к каждому узлу является post_id от узла posts. Это позволяет загружать сообщения в tableView без больших накладных расходов, и, например, если вы отображаете комментарии в detailView, загружайте все комментарии для определенного сообщения.
Обратите внимание, что узлы сообщений и ключи узлов комментариев создаются с помощью .childByAutoId ()
Теперь рабочий процесс. Предположим, что пользователь создает новый пост и ввел заголовок для поста и другой информации. Позвоните, чтобы создать сообщение в Firebase.
func createPost(withTitle: String, andCreatorUid: String) {
let postsRef = self.ref.child("posts")
let thisPost = postsRef.childByAutoId()
let d = [
"post_title": withTitle,
"creator_uid": andCreatorUid
]
thisPost.setValue(d)
}
Вот хитрый момент - то, что я делаю , имеет наблюдателя от узла сообщений. Когда добавляется новая запись, я получаю это событие, создаю объект PostsClass, который содержит информацию о записи, добавляет ее в мой массив dataSource, а затем обновляю tableView. Делая это, я также получаю ключ к узлу (который был создан с помощью .childByAutoId).
Другой пользователь видит это сообщение и хочет прокомментировать его, чтобы нажать на сообщение, чтобы ввести комментарий. Следующий код хранит их комментарий в Firebase.
func addComment(toPostId: String, andComment: String, commentByUid: String) {
let commentsRef = self.ref.child("comments") //ref to the comments node
let thisCommentRef = commentsRef.child(toPostId) //ref to a node with postId as key
let commentToAddRef = thisCommentRef.childByAutoId() //each comment will have it's own key
let d = [
"comment_text": andComment,
"comment_by_uid": commentByUid]
commentToAddRef.setValue(d)
}
toPostId - это ключ к сообщению, полученный из объекта PostClass, который они выбрали для добавления комментария.
Наконец, чтобы специально ответить на вопрос, здесь идет загрузка комментариев к конкретному сообщению.
func loadComments(forPostId: String) {
let ref = self.ref.child("comments")
let thisPostRef = ref.child(forPostId)
thisPostRef.observeSingleEvent(of: .value, with: { snapshot in
let allComments = snapshot.children.allObjects as! [DataSnapshot]
for commentSnap in allComments {
let commenterUid = commentSnap.childSnapshot(forPath: "comment_by_uid").value as? String ?? "No uid"
let commentText = commentSnap.childSnapshot(forPath: "comment_text").value as? String ?? "No comment"
//create a commentClass object, update properties and add to dataSourceArray
print(commenterUid, commentText)
}
//tableView reload
})
}
Примечания:
У меня есть класс var, ref , поэтому self.ref указывает на мой корневой узел firebase. Вам нужно будет установить это, чтобы указать на ваш
Я использую post_0 и comment_0 в качестве имен ключей узла в этом ответе, так как его легче читать и понимать, чем ключ, такой как -LhzJD3tPL0xcnUDMaOZ , который фактически создает .childByAutoId в вашей базе данных.