首页 > 解决方案 > 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!")
        }
    }
}

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

标签: iosswiftfirebasegoogle-cloud-firestoretransactions

解决方案


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


推荐阅读