Firebase Firestore:如何实现“点赞”系统?

Ant*_*ano 1 transactions ios firebase swift google-cloud-firestore

当当前用户点击 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
Run Code Online (Sandbox Code Playgroud)

这是我的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!")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道我的数据库是否以正确的、最具可扩展性的方式构建,以及我应该在哪里以及如何放置观察者来查看用户是否已经喜欢该帖子。

B S*_*now 5

在考虑扩展此方法的过程中,我意识到为什么不保存并加载用户喜欢的所有帖子 ID,而不是加载每个帖子的所有用户喜欢的帖子。一个帖子可以有 50k、500k 或 500 万个赞,但用户最多可能有 1-5k 个帖子赞。您可以在用户下创建一个“喜欢的帖子”集合,并且您可以在一次阅读中获取用户喜欢的所有帖子,这会快得多。