Firestore 数据不会显示在列表视图中。可识别设置不正确?

发布于 2025-01-11 02:27:49 字数 5392 浏览 1 评论 0原文

我正在尝试从 firebase 文档中获取一些数据并将其显示在 ListView 中。获取数据并将其解码到我自己的结构中效果很好(通过让控制台打印它进行测试),但它不会显示在实际的 ListView 中。我尝试创建 2 个示例数据集来查看我的 struct 和/或 ListView 的实现是否有任何问题,但它们显示得很好。 我最好的猜测是 ListView 对我从 firebase 文档中获得的 id 不满意。

这是我获取数据的方法(请暂时忽略 checkAvailablePkgs() 中丑陋的解决方案,这将会改变):

class firebaseController : ObservableObject {
    let databaseFIRB = Firestore.firestore()
    @Published var forUserAvailablePkgs : [DLPackage] = []
   
func checkAvailablePkgs() {
        if Auth.auth().currentUser != nil {
            var allAccessiblePkgs : [String] = []
            let userUID = Auth.auth().currentUser!.uid
            databaseFIRB.collection("user-access").document(userUID).getDocument { (document, error) in
                if let document = document, document.exists {
                    let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
                    let pkgArr = dataDescription.components(separatedBy: ", ")
                    for partString in pkgArr {
                        var tmpStringSlicing : String
                        tmpStringSlicing = partString.replacingOccurrences(of: "\": <null>", with: "")
                        tmpStringSlicing = tmpStringSlicing.replacingOccurrences(of: "[\\[\\]\"]", with: "", options: .regularExpression)
                        allAccessiblePkgs.append(tmpStringSlicing)
                    }
                    self.checkIndividualPkgInformation(pkgIDs: allAccessiblePkgs)
                } else {
                    print("Document does not exist")
                }
            }
        }
    }

    func checkIndividualPkgInformation(pkgIDs: [String]) {
        for id in pkgIDs {
            databaseFIRB.collection("download-pkgs").document(id).getDocument { (document, error) in
                if let document = document, document.exists {
                    let result = Result {
                        try document.data(as: DLPackage.self)
                    }
                    switch result {
                        case .success(let pkg):
                            if let pkg = pkg {
                                // A `Package` value was successfully initialized from the DocumentSnapshot.
                                print("Package: \(pkg)")
                                self.forUserAvailablePkgs.append(pkg)
                            } else {
                                // A nil value was successfully initialized from the DocumentSnapshot,
                                // or the DocumentSnapshot was nil.
                                print("Document does not exist")
                            }
                        case .failure(let error):
                            // A `City` value could not be initialized from the DocumentSnapshot.
                            print("Error decoding package: \(error)")
                        }
                } else {
                    print("Package-Document does not exist")
                }
            }
        }
    }
}

这是我想要将其保存为的结构:

struct DLPackage: Identifiable, Codable {
    @DocumentID var id = UUID().uuidString
    var name : String = ""
    var size : String = ""
    var contentpaths : [String] = [""]
}

这是拒绝显示获取的数据的 ListView :

struct FIRBauthView: View {
    let firebaseCtrl: firebaseController = firebaseController()
    var body: some View {
        VStack() {
            List(firebaseCtrl.forUserAvailablePkgs) {item in
                HStack() {
                    Text(String(item.name)).font(.custom("Avenir", size: 26))
                    Spacer()
                    Text(String(item.size)).font(.custom("Avenir", size: 26))
                }
            }
            Button {
                firebaseCtrl.checkAvailablePkgs()
            } label: {
                Text("Check")
            }
        }
    }
}

我可以给我的 firebaseControler().forUserAvailablePkgs 一个初始值:

forUserAvailablePkgs.append(contentsOf: [DLPackage(name: "Example", size: "1GB", contentpaths: ["hello","something"]),DLPackage(name: "Nr2", size: "1GB", contentpaths: ["hello","something else"])])

并且它们会很好地显示。

这是我从加载到 forUserAvailablePkgs 数组中的 firebase 数据中打印出来的:

[Light_Player.DLPackage(_id: FirebaseFirestoreSwift.DocumentID<Swift.String>(value: Optional("CDB68E0C-DCE2-4FAA-AD55-872322A55E56")), name: "Example", size: "1GB", contentpaths: ["hello", "something"]), 
Light_Player.DLPackage(_id: FirebaseFirestoreSwift.DocumentID<Swift.String>(value: Optional("DCAAF136-24FE-470A-B897-2D178AEDB3A0")), name: "Nr2", size: "1GB", contentpaths: ["hello", "something else"]), 
Light_Player.DLPackage(_id: FirebaseFirestoreSwift.DocumentID<Swift.String>(value: Optional("package2")), name: "Bewährte Klassiker", size: "3.4GB", contentpaths: ["placeholder for another path", "placeholder for a different path"]), 
Light_Player.DLPackage(_id: FirebaseFirestoreSwift.DocumentID<Swift.String>(value: Optional("package1")), name: "Basic", size: "7.3GB", contentpaths: ["placeholder for path", "placeholder for path 2"])]

我尝试将结构的 id 更改为:

@DocumentID var id: String?

因为我在在线教程中找到了它,但是代码不会以这种方式进行复制。

我还尝试在从数据库获取数据后使用生成的 UUID 覆盖 firebase 数据中的 id,但我仍然无法让 ListView 显示它。

任何帮助表示赞赏。

I'm trying to fetch some data from a firebase document and have it displayed in a ListView. Getting the data and decoding it into my own struct works fine (tested by letting the console print it), but it won't show up in the actual ListView. I tried to create 2 example datasets to see if there is anything wrong with the implementation of my struct and/or ListView, but those display just fine.
My best guess is that the ListView isnt happy with the id I get from the firebase document.

Here is how I fetch the data(pls ignore the ugly solution in checkAvailablePkgs() for now, that is going to change):

class firebaseController : ObservableObject {
    let databaseFIRB = Firestore.firestore()
    @Published var forUserAvailablePkgs : [DLPackage] = []
   
func checkAvailablePkgs() {
        if Auth.auth().currentUser != nil {
            var allAccessiblePkgs : [String] = []
            let userUID = Auth.auth().currentUser!.uid
            databaseFIRB.collection("user-access").document(userUID).getDocument { (document, error) in
                if let document = document, document.exists {
                    let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
                    let pkgArr = dataDescription.components(separatedBy: ", ")
                    for partString in pkgArr {
                        var tmpStringSlicing : String
                        tmpStringSlicing = partString.replacingOccurrences(of: "\": <null>", with: "")
                        tmpStringSlicing = tmpStringSlicing.replacingOccurrences(of: "[\\[\\]\"]", with: "", options: .regularExpression)
                        allAccessiblePkgs.append(tmpStringSlicing)
                    }
                    self.checkIndividualPkgInformation(pkgIDs: allAccessiblePkgs)
                } else {
                    print("Document does not exist")
                }
            }
        }
    }

    func checkIndividualPkgInformation(pkgIDs: [String]) {
        for id in pkgIDs {
            databaseFIRB.collection("download-pkgs").document(id).getDocument { (document, error) in
                if let document = document, document.exists {
                    let result = Result {
                        try document.data(as: DLPackage.self)
                    }
                    switch result {
                        case .success(let pkg):
                            if let pkg = pkg {
                                // A `Package` value was successfully initialized from the DocumentSnapshot.
                                print("Package: \(pkg)")
                                self.forUserAvailablePkgs.append(pkg)
                            } else {
                                // A nil value was successfully initialized from the DocumentSnapshot,
                                // or the DocumentSnapshot was nil.
                                print("Document does not exist")
                            }
                        case .failure(let error):
                            // A `City` value could not be initialized from the DocumentSnapshot.
                            print("Error decoding package: \(error)")
                        }
                } else {
                    print("Package-Document does not exist")
                }
            }
        }
    }
}

This is the struct I want to save it as:

struct DLPackage: Identifiable, Codable {
    @DocumentID var id = UUID().uuidString
    var name : String = ""
    var size : String = ""
    var contentpaths : [String] = [""]
}

And here is the ListView that refuses to Display the aquired data:

struct FIRBauthView: View {
    let firebaseCtrl: firebaseController = firebaseController()
    var body: some View {
        VStack() {
            List(firebaseCtrl.forUserAvailablePkgs) {item in
                HStack() {
                    Text(String(item.name)).font(.custom("Avenir", size: 26))
                    Spacer()
                    Text(String(item.size)).font(.custom("Avenir", size: 26))
                }
            }
            Button {
                firebaseCtrl.checkAvailablePkgs()
            } label: {
                Text("Check")
            }
        }
    }
}

I can give my firebaseControler().forUserAvailablePkgs an initial value of:

forUserAvailablePkgs.append(contentsOf: [DLPackage(name: "Example", size: "1GB", contentpaths: ["hello","something"]),DLPackage(name: "Nr2", size: "1GB", contentpaths: ["hello","something else"])])

and they will show up just fine.

This is my print from the firebase data loaded into the forUserAvailablePkgs Array:

[Light_Player.DLPackage(_id: FirebaseFirestoreSwift.DocumentID<Swift.String>(value: Optional("CDB68E0C-DCE2-4FAA-AD55-872322A55E56")), name: "Example", size: "1GB", contentpaths: ["hello", "something"]), 
Light_Player.DLPackage(_id: FirebaseFirestoreSwift.DocumentID<Swift.String>(value: Optional("DCAAF136-24FE-470A-B897-2D178AEDB3A0")), name: "Nr2", size: "1GB", contentpaths: ["hello", "something else"]), 
Light_Player.DLPackage(_id: FirebaseFirestoreSwift.DocumentID<Swift.String>(value: Optional("package2")), name: "Bewährte Klassiker", size: "3.4GB", contentpaths: ["placeholder for another path", "placeholder for a different path"]), 
Light_Player.DLPackage(_id: FirebaseFirestoreSwift.DocumentID<Swift.String>(value: Optional("package1")), name: "Basic", size: "7.3GB", contentpaths: ["placeholder for path", "placeholder for path 2"])]

I tried changing the id for the struct to:

@DocumentID var id: String?

since I found it in a tutorial online, however the code doesn't copile that way.

I also tried overwriting the ids from the firebase data with generated UUIDs after fetching the data from the database, but I still couldn't get the ListView to display it.

Any help is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白云悠悠 2025-01-18 02:27:49

经过一晚的良好睡眠后,我的暂时失明得到了治愈,并发现我在视图中缺少 @ObservedObject 属性。

struct FIRBauthView: View {
    @ObservedObject var firebaseCtrl: firebaseController = firebaseController()

而不是

struct FIRBauthView: View {
    let firebaseCtrl: firebaseController = firebaseController()

现在数据按预期显示。

Well after a good night of sleep I was cured of my temporary blindness and found that I was missing the @ObservedObject property in my view.

struct FIRBauthView: View {
    @ObservedObject var firebaseCtrl: firebaseController = firebaseController()

instead of

struct FIRBauthView: View {
    let firebaseCtrl: firebaseController = firebaseController()

Now the data is showing up as intended.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文