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

Swift中Firestore获取单个文档替代文档数组的实现方案咨询

Got it! The issue here is that your current code uses a query which returns a collection of documents (even if there's only one match), hence the array. Let's adjust this to fetch just that single matching document instead.

Step 1: Update your published property

First, change your array-type property to an optional single model instance — this makes sense because there might be no matching document, and we want to handle that case gracefully:

@Published var plantData: PlantDataModel? = nil

Step 2: Modify the loadData function

Since you mentioned plantId should uniquely identify a document, we can add .limit(to: 1) to the query to ensure Firestore only returns the first (and only) match. Then we'll extract that single document instead of mapping an array:

func loadData() {
    print("FIREBASE LOADING DETAIL DATA VIEW")
    db.collection("plantsData")
        .whereField("plantId", isEqualTo: plant.idPlant)
        .limit(to: 1) // Ensure we only get one matching document
        .addSnapshotListener { querySnapshot, error in
            // Handle errors first
            if let error = error {
                print("Error fetching data: \(error)")
                self.plantData = nil
                return
            }
            
            // Check if we have a matching document
            guard let matchingDocument = querySnapshot?.documents.first else {
                self.plantData = nil
                print("No document found for this plant ID")
                return
            }
            
            // Decode the single document
            do {
                self.plantData = try matchingDocument.data(as: PlantDataModel.self)
            } catch let decodeError {
                print("Error decoding plant data: \(decodeError)")
                self.plantData = nil
            }
        }
}

Bonus: One-time fetch (no real-time updates)

If you don't need to listen for real-time changes to the document, replace addSnapshotListener with getDocuments for a one-time fetch:

func loadDataOnce() {
    print("FIREBASE LOADING DETAIL DATA VIEW ONCE")
    db.collection("plantsData")
        .whereField("plantId", isEqualTo: plant.idPlant)
        .limit(to: 1)
        .getDocuments { querySnapshot, error in
            if let error = error {
                print("Error fetching data: \(error)")
                self.plantData = nil
                return
            }
            
            guard let matchingDocument = querySnapshot?.documents.first else {
                self.plantData = nil
                print("No document found for this plant ID")
                return
            }
            
            do {
                self.plantData = try matchingDocument.data(as: PlantDataModel.self)
            } catch let decodeError {
                print("Error decoding plant data: \(decodeError)")
                self.plantData = nil
            }
        }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:53:36