You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击点赞按钮后Feed帖子消失的Firestore技术问题排查

点赞后Feed帖子消失的问题排查与解决

问题场景

使用Firestore快照监听器加载动态Feed,点击点赞按钮更新帖子点赞数后,目标帖子会从Feed中消失,fetchUserPosts()输出调试信息显示数据库中无帖子,但Firestore后台的点赞数确实已成功增加。

相关代码

加载Feed帖子的函数

func fetchPosts() {
    let query = COLLECTION_POSTS
        .order(by: "timestamp", descending: true)

    query.addSnapshotListener { snapshot, _ in
        guard let changes = snapshot?.documentChanges.filter({$0.type == .added}) else {return}

        self.posts = changes.compactMap {
            do {
                return try $0.document.data(as: Post.self)
            } catch {
                print("Error converting Firestore document to Post object: \(error)")
                return nil
            }
        }
        self.fetchUserPosts()
    }
}

点赞更新函数

func likePost(post: Post) {
    guard let uid  = Auth.auth().currentUser?.uid else { return }
    guard let postId = post.id else { return }
    let userLikesRef = Firestore.firestore().collection("users").document(uid).collection("user-likes")
        
    Firestore.firestore().collection("posts").document(postId)
        .updateData(["likes" : post.likes + 1]) { _ in
            userLikesRef.document(postId).setData([:]) { _ in
                self.isLiked = true
            }
        }
}

问题原因

  1. 快照监听器仅处理.added变更:当点赞更新likes字段时,Firestore触发的是.modified类型的文档变更,但你的代码只过滤了.added类型的变更,此时changes为空数组,self.posts被直接赋值为空,导致帖子消失。
  2. fetchUserPosts()可能覆盖数据:每次快照触发都调用该函数,如果它的逻辑是直接替换self.posts数组,会进一步清空Feed数据。

解决方案

1. 修改快照监听器,处理所有变更类型

不要直接替换整个posts数组,而是根据变更类型更新现有数组:

func fetchPosts() {
    let query = COLLECTION_POSTS
        .order(by: "timestamp", descending: true)

    query.addSnapshotListener { snapshot, error in
        guard let snapshot = snapshot else {
            print("Error fetching posts: \(error?.localizedDescription ?? "Unknown error")")
            return
        }
        
        for change in snapshot.documentChanges {
            do {
                let updatedPost = try change.document.data(as: Post.self)
                switch change.type {
                case .added:
                    // 避免重复添加,保持时间戳降序
                    if !self.posts.contains(where: { $0.id == updatedPost.id }) {
                        self.posts.append(updatedPost)
                        self.posts.sort { $0.timestamp > $1.timestamp }
                    }
                case .modified:
                    // 找到对应帖子并更新数据
                    if let index = self.posts.firstIndex(where: { $0.id == updatedPost.id }) {
                        self.posts[index] = updatedPost
                    }
                case .removed:
                    // 移除已删除的帖子
                    self.posts.removeAll { $0.id == updatedPost.id }
                }
            } catch {
                print("Error converting Firestore document to Post object: \(error)")
            }
        }
        
        // 若fetchUserPosts()是加载用户自有帖子,需改为合并逻辑而非替换
        // self.fetchUserPosts()
    }
}

2. 优化点赞逻辑(可选)

点赞后可以先更新本地模型,提升用户体验,再等待Firestore回调确认:

func likePost(post: Post) {
    guard let uid  = Auth.auth().currentUser?.uid else { return }
    guard let postId = post.id else { return }
    let userLikesRef = Firestore.firestore().collection("users").document(uid).collection("user-likes")
    
    // 先更新本地模型
    if let index = self.posts.firstIndex(where: { $0.id == postId }) {
        var updatedPost = post
        updatedPost.likes += 1
        self.posts[index] = updatedPost
        self.isLiked = true
    }
        
    Firestore.firestore().collection("posts").document(postId)
        .updateData(["likes" : post.likes + 1]) { error in
            if let error = error {
                // 网络失败时回滚本地数据
                print("Failed to update likes: \(error)")
                if let index = self.posts.firstIndex(where: { $0.id == postId }) {
                    self.posts[index] = post
                    self.isLiked = false
                }
                return
            }
            userLikesRef.document(postId).setData([:])
        }
}

3. 检查fetchUserPosts()逻辑

确认该函数的作用,如果是加载用户自己的帖子,需要改为合并到现有posts数组,而不是直接替换,避免覆盖Feed数据。

内容的提问来源于stack exchange,提问作者user20072735

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 15:10:38