ios - Firebase Firestore:如何实现“点赞”系统?
问题描述
当 currentUser 点击 likeButton 时,我会运行一个事务,但我想检查用户是否已经喜欢该帖子。如果用户已经喜欢该帖子,我想减少 likeCounter 并更改 likeButton 的外观,否则我想增加它。
我的 Firestore 数据库使用 collection.document.collection.document.... 的东西:
"posts":
- "post1":
- uid: user1
- likeCount: 2
- caption: "caption1"
- "likes":
- "user1":
- value: true
- "user2":
- value: true
- "post2":
- uid: user1
- likeCount: 1
- caption: "caption2"
- "likes":
- "user1":
- value: true
- "user4":
- value: true
- "post3":
- uid: user2
- likeCount: 3
- caption: "caption3"
- "likes":
- "user1":
- value: true
- "user3":
- value: true
- "user4":
- value: true
这是我的 incrementLikes() 函数,每当用户点击 likeButton 时都会调用该函数
func incrementLikes() {
let ref = Api.Post.REF_POSTS.document(self.post!.id!)
Firestore.firestore().runTransaction({ (transaction, errorPointer) -> Any? in
let sfDocument: DocumentSnapshot
do {
try sfDocument = transaction.getDocument(ref)
} catch let fetchError as NSError {
errorPointer?.pointee = fetchError
return nil
}
guard let oldLikes = sfDocument.data()?["likeCount"] as? Int else {
let error = NSError(
domain: "AppErrorDomain",
code: -1,
userInfo: [
NSLocalizedDescriptionKey: "Unable to retrieve likes from snapshot \(sfDocument)"
]
)
errorPointer?.pointee = error
return nil
}
transaction.updateData(["likeCount": oldLikes - 1], forDocument: ref)
if let currentUser = Auth.auth().currentUser {
ref.collection(K.likesCollection).document(currentUser.uid).delete()
}
DispatchQueue.main.async {
self.likeImageView.image = UIImage(systemName: K.heart)
self.likeImageView.tintColor = UIColor.black
}
return nil
}) { (object, error) in
if let error = error {
print("Transaction failed: \(error)")
} else {
print("Transaction successfully committed!")
}
}
}
我想知道我的数据库是否以最可扩展的正确方式构建,以及我应该在哪里以及如何放置观察者以查看用户是否已经喜欢该帖子。
解决方案
在考虑一种扩展方式时,我意识到不是为每个帖子加载所有用户喜欢的内容,为什么不保存并加载用户喜欢的所有帖子 ID。一个帖子可以有 50k、500k 或 500 万个赞,但一个用户可能最多有 1-5k 个帖子赞。您可以在用户下创建一个“喜欢的帖子”集合,您可能可以在一次阅读中获取用户喜欢的所有帖子,这会更快。
推荐阅读
- jquery - SlideToggle 列表关闭时仅显示列表的一部分
- kotlin - 绑定不同视图模型的脏属性
- xml - 如何使用评估
- scala - Binding.scala:避免过多 dom-tree 更新的策略
- vba - EXCEL VBA ,仅在条件验证时才允许
- c# - UWP Pivot 控件,如何将焦点设置到 PivotItem 中的第一个控件
- ios - swift中嵌套字典API的结构
- java - 项目构建错误:不可解析的父 POM。org.springframework.boot:spring-boot-starter-parent 传输失败
- c++ - C ++如何将连续的区间插入std :: vector?
- javascript - 添加 style.css 时 angular-cli.json 创建错误