Ios Firebase Firestore:如何实施;“喜欢”;系统

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: "

当当前用户点击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!")
        }
    }
}

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

当我使用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调用在主线程上运行,而网络调用在后台线程上自动运行。但是,如果您想查看用户是否喜欢帖子,您将加载所有用户喜欢的帖子?啊,是,真的。我没有想到这一点,因为我的应用程序非常小。我想这毕竟不是最好的方法。