尽管querySnapshot包含文档,但为什么要使用compactMap将Firestore querySnapshot转换为自定义对象却返回空?

问题描述 投票:0回答:1

Screenshot of a Firestore Document

我正在使用Swift,Xcode和Firestore数据库。我创建了TableView和带有字典的自定义对象类(MediumSample),并希望加载Firestore文档并在TableView中显示它们。

[文档(屏幕快照中的示例)已从Firestore正确加载,但无法转换为对象。从compactMap返回的对象列表始终为空。

这是我的代码段。如果有人对出了什么问题有暗示,那就太好了。

自定义对象类(简化):

import Foundation
import FirebaseFirestore

protocol MediumSampleDocumentSerializable {
    init?(dictionary: [String:Any])
}

struct MediumSample {

    var id: String
    var field_t: String
    var field_i: Int64
    var field_b1: Bool
    var field_b2: Bool
    var field_g: FirebaseFirestore.GeoPoint
    var field_d: Date
    var field_a: [String]
    var usecase: String


    var dictionary: [String:Any] {
         return [
             "id": id,
             "field_t": field_t,
             "field_i": field_i,
             "field_b1": field_b1,
             "field_b2": field_b2,
             "field_g": field_g,
             "field_d": field_d,
             "field_a": field_a,
             "usecase": usecase
         ]
     }

}

extension MediumSample: MediumSampleDocumentSerializable {
    init?(dictionary: [String:Any]) {
        guard let id = dictionary ["id"] as? String,
        let field_t = dictionary ["field_t"] as? String,
        let field_i = dictionary ["field_i"] as? Int64,
        let field_b1 = dictionary ["field_b1"] as? Bool,
        let field_b2 = dictionary ["field_b2"] as? Bool,
        let field_g = dictionary ["field_g"] as? FirebaseFirestore.GeoPoint,
        let field_d = dictionary ["field_d"] as? Date,
        let field_a = dictionary ["field_a"] as? [String],
        let usecase = dictionary ["usecase"] as? String else {return nil}

        self.init (id: id, field_t: field_t, field_i: field_i, field_b1: field_b1, field_b2: field_b2, field_g: field_g, field_d: field_d, field_a: field_a, usecase: usecase)
    }

}

声明数据库和数组并调用加载函数:

import UIKit
import FirebaseFirestore

class MediumTableViewController: UITableViewController {

    //MARK: Properties

    var db: Firestore!
    var mediumsamples = [MediumSample]()

    override func viewDidLoad() {
        super.viewDidLoad()

        db = Firestore.firestore()
        loadMediumSamples()

    }

加载Firestore文档以填充数组的功能:

    private func loadMediumSamples() {

               //run the Firestore query
               db.collection(Constants.MEDIUMS).whereField("usecase", isEqualTo: Constants.USECASE)
                   .getDocuments() { querySnapshot, err in
                       if let err = err {
                           print("Error getting documents: \(err)")
                       } else {

                        //initialise an array of medium objects with Firestore data snapshots
                        self.mediumsamples = querySnapshot!.documents.compactMap({MediumSample(dictionary: $0.data())})

                        //fill the tableView
                        DispatchQueue.main.async {
                            self.tableView.reloadData()
                            print(self.mediumsamples)
                        }

                        print("Mediums List", self.mediumsamples) // This line returns: Mediums List []

                        print("Mediums List size", (self.mediumsamples.count)) // This line returns: Mediums List size 0

                        for document in querySnapshot!.documents {
                            print("\(document.documentID) => \(document.data())") // This line returns the snapshot documents correctly!

                        }
                       }
               }
    }

以下是添加截图对象的方法:

    func addMediumSamples() {

        let currentDateTime = Date()
        let location = FirebaseFirestore.GeoPoint(latitude: 0, longitude: 0)
        let mediumsample = MediumSample(id: "an id", field_t: "field_t", field_i: 10, field_b1: true, field_b2: false, field_g: location, field_d: currentDateTime, field_a: [Constants.SAMPLE_DEV], usecase: Constants.SAMPLE_DEV)

        var ref: DocumentReference? = nil
        ref = self.db.collection(Constants.MEDIUMS).addDocument(data: mediumsample.dictionary) {
            error in
            if let error = error {
                print("Error writing city to Firestore: \(error)")
            } else {
                print("Document added with id : \(ref!.documentID)")
            }
        }

    }

swift firebase google-cloud-firestore flatmap
1个回答
0
投票

问题出在MediumSample struct中,在field_d类型(日期)中。Cloud Firestore数据库中该字段的类型为Timestamp

MediumSample结构中的字段“ field_d”期望值为类型[[日期。

您可以将类型更改为

FirebaseFirestore.Timestamp

,或者可以在映射时以及传递给MediumSample之前将其转换为Date例如在Swift中将时间戳转换为日期

让日期= timestamp.dateValue()
© www.soinside.com 2019 - 2024. All rights reserved.