Вот очень сокращенный код для выполнения sh задачи добавления пользователя uid, которому нравится публикация, и увеличения счетчика с помощью runTransactionBlock. Имейте в виду, что есть 100 способов сделать это.
Предлагаемая структура
all_posts
post_0
like_count: 2
post: "Hello, World"
likes
post_0
uid_0: true
uid_1: true
На основе вопроса и обсуждения я разбил посты и лайки на отдельные узлы. Причина в том, что когда сообщения загружены, они, вероятно, будут отображаться в списке, и все, что действительно нужно в этот момент, - это запись topi c и общее количество лайков, поэтому я включил «like_count» в сообщение. узел.
Если бы мы добавили фактические лайки в самом почтовом узле, это может быть 10 000 или 10 000 000, и нет никакой причины загружать все эти данные при загрузке в сообщениях. Наличие такого количества лайков также может привести к перегрузке устройства.
Внутри узла лайков каждый ключ поста ссылается на пост в узле all_posts. Дети - это UID пользователей, которым понравился пост, а значение - логическое «true» в качестве заполнителя. Узлы без значений не могут существовать, поэтому «true» сохраняет их на месте и представляет собой небольшое количество данных.
Тогда код -
func updatePostWithLikesViaTransaction() {
let postsRef = self.ref.child("all_posts") //self.ref points to my Firebase
let thisPostRef = postsRef.child("post_0")
thisPostRef.runTransactionBlock ({ (currentData: MutableData) -> TransactionResult in
if var data = currentData.value as? [String: Any] {
var count = data["like_count"] as? Int ?? 0
count += 1
data["like_count"] = count
currentData.value = data
}
return TransactionResult.success(withValue: currentData)
}) { (error, committed, snapshot) in
if let error = error {
print(error.localizedDescription)
return
}
print("successfully incremented counter")
let likesRef = self.ref.child("likes")
let likesPostRef = likesRef.child(thisPostRef.key!)
likesPostRef.child("uid_2").setValue(true)
}
}
Вышеприведенное не является идеальным, но демонстрирует процесс (и работает с представленной структурой).
Сначала мы получаем ссылку на сообщение, которое мы хотим обновить, а затем в блоке транзакции читаем дочерний элемент current_ata 'like_count', который возвращает 2 на основе значения в структуре. Увеличивается до 3, обновляется в currentData, а затем обновляется через TransactionResult.
runTransactionBlock также имеет необязательный обратный вызов завершения, и мы используем его для успешного обновления сообщения в лайках, используя uid и true пользователей. .
Конечным результатом выполнения этого является то, что счетчик увеличивается до 3, а 'uid_2: true' добавляется к узлу «likes / post_0 '