【问题标题】:Assigning firestore data to custom object将 Firestore 数据分配给自定义对象
【发布时间】:2020-12-15 14:56:26
【问题描述】:

我正在尝试制作一个使用 Firestore 来存储客户特定规格的应用。我有一个目前只有几个属性的规范对象,但我需要获取数据并将其分配给一个新的规范对象,然后将其附加到一个数组以显示在 tableView 上。我不明白如何访问数组中的各个映射以将值分配给规范的每个属性。我目前将它设置为在控制台中打印,因为每次我尝试从文档中分配一个值时它都是 nil。本质上,我需要将数据存储在客户(所有客户的总列表)下,并且在其他数据中,有一个包含每个客户的 specNumber、specDescription 和palletCount 的规格数组。

示例:

Customer: Test
Specs:
3096:
    Description: 50#top
    pltCount: 250
3097:
    Description: 50#bottom
    pltCount: 250

Firestore 数据: enter image description here

代码:

    let settings = FirestoreSettings()
    
    Firestore.firestore().settings = settings
    
    db = Firestore.firestore()
    
    
    db.collection("customers/test/specs")//.whereField("isCustomer", isEqualTo: true)
        .getDocuments() { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {

                    print("\(document.documentID) => \(document.data())")
                    
                }
            }
    }

规范调用代码:

struct Spec {
    
    // Properties
    var specNumber: String
    var specDescription: String
    var palletCount: Int
    //var palletsOrdered = 0

    init(specNum: Int, specDesc: String, pltCount: Int) {

        specNumber = "\(specNum)"
        specDescription = specDesc
        palletCount = pltCount

    } 
}

【问题讨论】:

    标签: ios swift firebase google-cloud-firestore swift5


    【解决方案1】:

    您必须将对文档的访问与对文档内数据的访问分开(您尝试同时进行)。您不能在文档或文档中的字段上调用getDocuments(),只能在集合上调用。所以不要db.collection("customers/test/specs").getDocuments(),试试:

    db.collection("customers").getDocuments() { (snapshot, error) in ... }
    

    然后从文档中获取数据:

    db.collection("customers").getDocuments() { (snapshot, error) in
        if let snapshot = snapshot { // lead by unwrapping the snapshot instead of the error
            for doc in snapshot.documents { // iterate through the documents
                guard let specs = doc.get("specs") as? [[String: Any]] else {
                    continue // continue loop
                }
                for s in specs { // iterate through the array of specs
                    if let specNum = s["SpecNum"] as? String,
                        let specDesc = s["SpecDesc"] as? String,
                        let pltCount = s["PalletCount"] as? Int {
                            let spec = Spec(specNum: specNum, specDesc: specDesc, pltCount: pltCount)
                            self.someArray.append(spec)
                        }
                }
    
                self.tableView.reloadData() // loop is done, reload
            }
        } else {
            if let error = error {
                print(error)
            }
        }
    }
    

    这是一个非常简化的版本,我认为您实际上想要实现它,具体取决于重新加载表/集合的方式(即时、常规或仅一次)。此外,每个文档都包含一系列规范,但您从集合中获取所有文档,这将为您提供大量规范,而没有任何说明哪个规范与哪个客户相关联。但我怀疑这只是早期设置,您只是想先处理 API。

    注意:Firestore 中的地图在 Swift 中称为字典,它们总是从 Firestore 以[String: Any] 字典形式返回。这就是为什么当我们最初打开规格图时,我们将其转换为字典数组:

    let specs = doc.get("specs") as? [[String: Any]]
    

    【讨论】:

    • 谢谢!!!我已经坚持了一段时间。也谢谢你的解释,对我帮助很大。我认为理想情况下我会在应用程序打开后调用它,因为客户的规格不会经常改变。再次感谢您!
    • 我将如何考虑不同的客户?因此,如果我将另一个客户添加为 test2,我无法执行 db.collection("customers/test2").getDocuments() { (snapshot, error) in ... } 来提取他们的规格。我进一步知道它不会被硬编码,而是基于哪个用户登录的字符串变量。
    • 我知道如果我重命名每个数组 customerNameSpecs 并让它成为一个变量,该变量会根据登录的用户而变化,那么它只会拉取他们的规格。然后我可以打电话。守卫 let specs = doc.get("customerNamespecs") as? [[String: Any]] else { 我只是想知道他们是否是更好的方法。
    • db.document("customers/test2").getDocument() { snapshot error in ... } 是你会做的。很难说如何在不了解数据的情况下构建您的数据,但我想您希望每个客户都有一个单独的文档,或者每个规范都有一个单独的文档。 Firestore 不仅最适合处理大量小文档,而且每个文档都有大小限制(集合没有)。因此,如果客户有数十或数百个规格,您最好为每个规格提供自己的文档。要查找给定用户的所有规范,请查询 userId 字段等于用户 ID 的集合。
    • 如果我这样做,我会得到“线程 1:异常:”无效的集合引用。集合引用必须有奇数个段,但客户/test2 有 2"。根据您所说的,将集合作为规范编号是否更有意义,并且在字段内有诸如托盘侦察和描述之类的内容?在最大客户将只有 200 个规格。我正在考虑按 userId 进行过滤,只是想考虑构造数据以包含它的最佳方法,谢谢。
    猜你喜欢
    • 2018-11-13
    • 2021-12-11
    • 2021-06-29
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    • 2017-09-05
    • 1970-01-01
    相关资源
    最近更新 更多