Ios Firebase Firestore:如何实施;“喜欢”;系统
当当前用户点击likeButton时,我运行一个事务,但我想检查用户是否已经喜欢该帖子。如果用户已经喜欢这篇文章,我想减少likeCounter并更改likeButton的外观,否则我想增加它 我的Firestore数据库正在使用collection.document.collection.document。。。。材料:Ios Firebase Firestore:如何实施;“喜欢”;系统,ios,swift,firebase,google-cloud-firestore,transactions,Ios,Swift,Firebase,Google Cloud Firestore,Transactions,当当前用户点击likeButton时,我运行一个事务,但我想检查用户是否已经喜欢该帖子。如果用户已经喜欢这篇文章,我想减少likeCounter并更改likeButton的外观,否则我想增加它 我的Firestore数据库正在使用collection.document.collection.document。。。。材料: "posts": - "post1": - uid: user1 - likeCount: 2 - caption: "
"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!")
}
}
}
我想知道我的数据库是否以最可伸缩的方式构建,以及我应该将观察者放置在何处以及如何放置,以查看用户是否已经喜欢该帖子。当我使用Firebase制作社交媒体平台时,使用帖子中的子帖子数量更容易获得
likeCounter
。然后,当检查likeButton
是否应该显示它是否喜欢时,只需查看它们的用户ID
是否在子项中
我发现这更好的原因是:
"posts":
- "post1":
- uid: user1
- caption: "caption1"
-"LikedBy":
-LikedBy:"user1"
-LikedBy:"user3"
// we added "LikedBy": so that instead of using likeCounter,
//you could get the count from it's children.
//To see if it's already liked by the user,
// find the name in this branch. If user1 finds his name in the children,
//it'll return true. That means he's liked it.
- "post2":
- uid: user1
- caption: "caption2"
-"LikedBy":
-LikedBy:"user1"
-LikedBy:"user3"
- "post3":
- uid: user2
- caption: "caption3"
-"LikedBy":
-LikedBy:"user1"
-LikedBy:"user2"
-LikedBy:"user3"
// as you can see this is no longer used
"likesPerUser":
- "user1":
- "user2":
- "user3":
在考虑一种扩展方法时,我意识到,与其为每个帖子加载用户喜欢的所有帖子ID,不如保存并加载用户喜欢的所有帖子ID。一个帖子可以有5万、5万或500万个喜欢,但一个用户最多可能有1-5万个帖子喜欢。您可以在用户下创建一个“喜欢的帖子”集合,您可能可以在一次阅读中获取用户喜欢的所有帖子,这将更快。问题有点不清楚。如果您想检查用户是否喜欢帖子-这可以通过观察SingleEvent用户喜欢该关键字的帖子来完成,如果它存在,则减少帖子的likeCounter。您甚至不需要查询,因为您知道post id以查看它是否存在。阅读数据包含在《入门指南》中。如果这不是你要问的,你能澄清这个问题吗?谢谢你的回答,但我使用的是Firestore非实时数据库,因此无法使用observingSingleEvent方法,有没有一种方法可以用Firestore实现它?还有,在runTransaction方法中我应该将观察者放在哪里?再次感谢哎呀,对不起。事实上,Firestore中也存在一次获取数据的概念,其用法类似。获取文档,如果它存在(document.exists),则减少likeCounter。此外,Firebase闭包中不需要此DispatchQueue.main.async,因为UI调用在主线程上运行,而网络调用在后台线程上自动运行。但是,如果您想查看用户是否喜欢帖子,您将加载所有用户喜欢的帖子?啊,是,真的。我没有想到这一点,因为我的应用程序非常小。我想这毕竟不是最好的方法。