You need to enable JavaScript to run this app. 使用addSnapshotListener异步获取Firebase数据元素数量问题求解
优惠活动
大模型
产品
解决方案
定价
更多

使用addSnapshotListener异步获取Firebase数据元素数量问题求解

问题修复方案

根因说明

  • ViewModel 中定义的监听方法全程没有被调用,Firestore 的数据监听逻辑从未执行,无法拉取到远端数据
  • Firestore 的 addSnapshotListener 是异步回调方法,你在 onAppear 中同步读取数组长度时,网络请求还没返回,拿到的永远是初始值 0
  • 额外定义的 @State var count 没有和 ViewModel 中的 @Published 属性绑定,就算后续数组数据更新,count 也不会同步刷新视图

修复后的代码

ViewModel.swift

import Foundation
import SwiftUI
import Firebase

class ViewModel: ObservableObject {
    // @Published 标记的属性变更时会自动通知关联视图刷新
    @Published var array = [Any]()

    func addSnapshotListener() {
        Firestore.firestore().collection("Posts").addSnapshotListener { [weak self] snap, err in
            guard let self = self, let docs = snap, err == nil else { return }
            // 每次获取新快照先清空旧数据,避免后续文档变更时重复累加
            self.array.removeAll()
            docs.documentChanges.forEach { doc in
                self.array.append(doc)
            }
        }
    }
}

CheckArrayCount.swift

import SwiftUI
    
struct CheckArrayCount: View {
    @StateObject var viewModel = ViewModel()

    var body: some View {
        VStack{
            // 直接读取 @Published 属性的长度,数据更新时会自动刷新 Text 展示
            Text("arrayCount:\(viewModel.array.count)")
        }
        .onAppear {
            // 触发Firestore监听调用,之前的代码遗漏了这一步
            viewModel.addSnapshotListener()
        }
    }
}

额外注意事项

  • 闭包中使用 [weak self] 是为了避免循环引用,防止 ViewModel 无法正常释放造成内存泄漏
  • 每次拿到新快照先清空原有数组,是为了避免后续文档新增/修改/删除触发回调时,重复累加相同的文档数据
  • 不需要额外定义中间变量 count 存储数组长度,直接读取 @Published 修饰的数组属性的长度即可,视图会自动跟随属性变更刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 19:45:10