查询文档并返回其子集合

huangapple go评论73阅读模式
英文:

Querying a document and returning its subcollection

问题

高级描述。我有一个名为“venues”的集合。每个场馆都有一个名为“food”的子集合。Firestore路径为“> venues > {DocumentID} food {DocumentID}”

在SwiftUI中,我正在传递venueID(documentID),并希望显示与我传递的venueID相关的food集合中的所有项目。

我知道venueID已成功传递,并且所选的venueID确实有一个名为'food'的子集合,其中包含多个文档。这是我目前的情况。我继续收到“无法读取数据,因为它丢失。”的错误消息。

struct SettingsView: View {
    var body: some View {
        NavigationView {
            List {
                Section("General") {
                    NavigationLink("Applications", destination: ApplicationsView())
                }
                Section("Calendar") {
                    NavigationLink("Outlook", destination: OutlookView())
                    NavigationLink("Google", destination: GoogleCalendarView())
                }
            }
            .navigationTitle("Settings")
            .listStyle(.sidebar)
        }
        .padding()
    }
}

struct ApplicationsView: View {
    var body: some View {
        Text("Applications")
    }
}

struct OutlookView: View {
    var body: some View {
        Text("Outlook")
    }
}

struct SettingsView_Previews: PreviewProvider {
    static var previews: some View {
        SettingsView()
    }
}

struct Venue: Codable, Identifiable {
    var id: String
    let title: String
    let venueArea: String
    let festivalID: String
    let fileURL: String
    let description: String
}

struct FoodItem: Codable, Identifiable {
    var id: String
    var itemName: String
    var itemDescription: String
    var photoURL: String
    var itemPrice: Int
    var DDPSnack: Bool
    var alcohol: Bool
    var gardenGraze: Bool
    var plantBased: Bool
}

class FoodViewModel: ObservableObject {
    @Published var foodItems = [FoodItem]()

    private var db = Firestore.firestore()
    private var foodRef: CollectionReference?

    init(venueID: String) {
        foodRef = db.collection("venues").document(venueID).collection("food")
        fetchData()
    }

    func fetchData() {
        foodRef?.getDocuments { snapshot, error in
            if let error = error {
                print("Error fetching food items: \(error.localizedDescription)")
                return
            }

            guard let documents = snapshot?.documents else {
                print("No documents found")
                return
            }

            self.foodItems = documents.compactMap { document in
                let result = Result {
                    try document.data(as: FoodItem.self)
                }
                switch result {
                case .success(let foodItem):
                    return foodItem
                case .failure(let error):
                    print("Error decoding food item: \(error.localizedDescription)")
                    return nil
                }
            }
        }
    }
}

struct VenueMenu: View {
    @ObservedObject var viewModel: FoodViewModel
    var venueID: String

    init(venueID: String) {
        self.venueID = venueID
        viewModel = FoodViewModel(venueID: venueID)
    }

    var body: some View {
        VStack {
            Text(venueID) // 在此处显示venueID
            List(viewModel.foodItems, id: \.id) { foodItem in
                VStack(alignment: .leading) {
                    Text(foodItem.itemName)
                    Text("\(foodItem.itemPrice)")
                }
            }
        }
    }
}
英文:

High level description. I have a collection named "venues". Each venue has a subcollection named "food". The firestore path is "> venues > {DocumentID} food {DocumentID}"

In SwiftUI, I'm passing the venueID (documentID) and I want to display all of the items in the food collection that relates to the venueID that I'm passing.

I know the venueID is successfully being passed and the selected venueID does in fact have a subcollection of 'food' with multiple documents. Here's what I have right now. I continue to get "The data couldn't be read because it's missing."

struct SettingsView: View {
var body: some View {
//        HStack{
NavigationStack {
List {
Section("General") {
NavigationLink("Applications", value: "app")
}
Section("Calendar") {
NavigationLink("Outlook", value: "outlook")
NavigationLink("Google", value: "gCalendar")
}
}
.navigationTitle("Settings")
.listStyle(.sidebar)
}
VStack {
// How to change this once the item is clicked?
ApplicationsView()
}
//        }
.padding()
}
}
struct ApplicationsView: View {
var body: some View {
Text("Applications")
}
}
struct OutlookView: View {
var body: some View {
Text("Outlook")
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}
struct Venue: Codable, Identifiable {
var id: String
let title: String
let venueArea: String
let festivalID: String
let fileURL: String
let description: String
}
struct FoodItem: Codable, Identifiable {
var id: String
var itemName: String
var itemDescription: String
var photoURL: String
var itemPrice: Int
var DDPSnack: Bool
var alcohol: Bool
var gardenGraze: Bool
var plantBased: Bool
}
class FoodViewModel: ObservableObject {
@Published var foodItems = [FoodItem]()
private var db = Firestore.firestore()
private var foodRef: CollectionReference?
init(venueID: String) {
foodRef = db.collection("venues").document(venueID).collection("food")
fetchData()
}
func fetchData() {
foodRef?.getDocuments { snapshot, error in
if let error = error {
print("Error fetching food items: \(error.localizedDescription)")
return
}
guard let documents = snapshot?.documents else {
print("No documents found")
return
}
self.foodItems = documents.compactMap { document in
let result = Result {
try document.data(as: FoodItem.self)
}
switch result {
case .success(let foodItem):
return foodItem
case .failure(let error):
print("Error decoding food item: \(error.localizedDescription)")
return nil
}
}
}
}
}
struct VenueMenu: View {
@ObservedObject var viewModel: FoodViewModel
var venueID: String
init(venueID: String) {
self.venueID = venueID
viewModel = FoodViewModel(venueID: venueID)
}
var body: some View {
VStack {
Text(venueID) // display the venueID here
List(viewModel.foodItems, id: \.id) { foodItem in
VStack(alignment: .leading) {
Text(foodItem.itemName)
Text("\(foodItem.itemPrice)")
}
}
}
}
}

答案1

得分: 1

将以下内容翻译为中文:

print("Error decoding food item: \(error.localizedDescription)")

更改为

print("Error decoding food item: \(error)")

这样你会得到一个更具描述性的错误,你可能需要通过在变量末尾添加 ? 来使一个或多个变量成为可选项。

英文:

Change

 print("Error decoding food item: \(error.localizedDescription)")

To

 print("Error decoding food item: \(error)")

You'll get a more descriptive error, you will likely have to make one or more of the variables optional by adding ? at the end.

huangapple
  • 本文由 发表于 2023年6月1日 23:44:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76383639.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定