Firestore 不保存数据

Firestore doesn't save data

我正在尝试制作一个简单的应用程序,让用户可以创建食谱,然后将它们上传到 firestore

我正在使用环境对象来存储数据,直到我将其上传到 firestore

我的问题是,当我检查 firestore 以查看我的数据是否已上传时,那里的数据是空的

这是我的食谱class:

import Foundation

class recipe: ObservableObject{
    @Published var name: String = ""
    @Published var prepMins: Int = 0
    @Published var prepHours: Int = 0
    @Published var cookMins: Int = 0
    @Published var cookHours: Int = 0
    @Published var restMins: Int = 0
    @Published var restHours: Int = 0
    @Published var dishType: String = ""
    @Published var cuisine: String = ""
    @Published var difficulty: String = ""
    @Published var instructions: [String] = []
    @Published var ingredients: [String] = []
}

这是一个示例上传视图:

import SwiftUI

struct UploadView: View {
    
    @State private var dishType = "Starter"
    @State private var cuisine = "European"
    @State private var difficulty = "Easy"
    @State var name: String = ""
    @State private var isPresented = false
    @State private var isPresented1 = false
    
    @State var prepHours: Int = 0
    @State var prepMins: Int = 0
    @State var cookHours: Int = 0
    @State var cookMins: Int = 0
    @State var restHours: Int = 0
    @State var restMins: Int = 0
    
    @StateObject var recipe1 = recipe()
    
    @EnvironmentObject var viewRouter: ViewRouter
    
    var options = ["Easy", "Medium", "Difficult"]
    
    var body: some View {
        ScrollView{
            VStack{
                HStack{
                    Spacer()
                    Text("Create a Recipe")
                        .font(.system(size: 30))
                        .fontWeight(.bold)
                    Spacer()
                }
                .padding(.top)
            }
            Group{
                HStack{
                    Text("Name")
                        .padding()
                        .font(.system(size: 25, weight: .medium))
                    Spacer()
                }
                HStack{
                    TextField("Enter a name", text: $name)
                        .padding()
                    
                        .zIndex(1)
                    Spacer()
                }
            }
            Group{
                HStack{
                    Text("Choose a dish type")
                        .padding()
                    Spacer()
                }
                
                HStack{
                    Button(dishType) {
                        isPresented.toggle()
                        
                    }
                    .fullScreenCover(isPresented: $isPresented) {
                        SelectionView()
                    }
                    Spacer()
                }
                .padding(.horizontal)
                
                
                
                HStack{
                    Text("Choose a cuisine")
                    
                    
                        .padding()
                    Spacer()
                }
                
                HStack{
                    Button(cuisine) {
                        isPresented1.toggle()
                    }
                    .fullScreenCover(isPresented: $isPresented1) {
                        SelectionView1()
                    }
                    Spacer()
                }
                .padding(.horizontal)
                
                
                
            }
            HStack{
                Text("Choose a difficulty")
                    .padding()
                Spacer()
            }
            Picker("Diffuculty", selection: $difficulty) {
                ForEach(options, id: \.self) {
                    Text([=11=])
                }
            }
            .pickerStyle(.segmented)
            .padding(.horizontal)
            .padding(.bottom)
            Group{
                
                VStack{
                    HStack{
                        Text("Prep Time")
                            .fontWeight(.medium)
                            .padding(.horizontal)
                            .padding(.bottom)
                        Spacer()
                    }
                    
                    HStack{
                        Text("How long does it take to make the dish")
                            .fontWeight(.light)
                            .padding(.horizontal)
                        Spacer()
                    }
                    
                }
                HStack{
                    HStack{
                        VStack {
                            Picker("", selection: $prepHours){
                                ForEach(0..<12, id: \.self) { i in
                                    Text("\(i) hours").tag(i)
                                }
                            }
                        }
                        VStack {
                            Picker("", selection: $prepMins){
                                ForEach(0..<60, id: \.self) { i in
                                    Text("\(i) min").tag(i)
                                }
                            }
                        }
                        
                    }
                    .padding(.horizontal)
                    .padding(.bottom)
                    Spacer()
                }
                VStack{
                    
                    VStack{
                        HStack{
                            Text("Cook Time")
                                .fontWeight(.medium)
                                .padding(.horizontal)
                                .padding(.bottom)
                            Spacer()
                        }
                        HStack{
                            Text("How long does it take to cook the dish")
                                .fontWeight(.light)
                                .padding(.horizontal)
                            Spacer()
                            
                        }
                        
                    }
                    
                }
                HStack{
                    HStack{
                        VStack {
                            Picker("", selection: $cookHours){
                                ForEach(0..<12, id: \.self) { i in
                                    Text("\(i) hours").tag(i)
                                }
                            }
                        }
                        VStack {
                            Picker("", selection: $cookMins){
                                ForEach(0..<60, id: \.self) { i in
                                    Text("\(i) min").tag(i)
                                        .foregroundColor(.black)
                                }
                            }
                        }
                        
                    }
                    .padding(.horizontal)
                    .padding(.bottom)
                    Spacer()
                }
                VStack{
                    
                    VStack{
                        HStack{
                            Text("Rest Time")
                                .fontWeight(.medium)
                                .padding(.horizontal)
                                .padding(.bottom)
                            Spacer()
                        }
                        
                        HStack{
                            Text("How long does the dish need to rest")
                                .fontWeight(.light)
                                .padding(.horizontal)
                            Spacer()
                        }
                        
                    }
                    
                }
                HStack{
                    HStack{
                        VStack {
                            Picker("", selection: $restHours){
                                ForEach(0..<12, id: \.self) { i in
                                    Text("\(i) hours").tag(i)
                                }
                            }
                        }
                        VStack {
                            Picker("", selection: $restMins){
                                ForEach(0..<60, id: \.self) { i in
                                    Text("\(i) min").tag(i)
                                        .foregroundColor(.black)
                                }
                            }
                        }
                        
                    }
                    .padding(.horizontal)
                    .padding(.bottom)
                    Spacer()
                }
            }
            
            Button {
                //change view router
                //add data to data class
                recipe1.name = name
                recipe1.dishType = dishType
                recipe1.cuisine = cuisine
                recipe1.difficulty = difficulty
                recipe1.prepMins = prepMins
                recipe1.prepHours = prepHours
                recipe1.cookMins = cookMins
                recipe1.cookHours = cookHours
                recipe1.restMins = restMins
                recipe1.restHours = restHours
                viewRouter.currentPage = .uploadView2
            } label: {
                Label("next", systemImage: "arrow.right")
            }
            
            .padding()
            .frame(width: 100)
            .foregroundColor(Color.white)
            .background(Color.red)
            .cornerRadius(8)
        }
        .environmentObject(recipe1)
    }
}



struct UploadView_Previews: PreviewProvider {
    static var previews: some View {
        UploadView()
            .previewDevice(PreviewDevice(rawValue: "iPhone 13"))
        UploadView()
            .previewDevice(PreviewDevice(rawValue: "iPhone 8"))
    }
}

这是我对上传功能的最终看法

import SwiftUI
import Firebase

struct UploadView3: View {
    
    @EnvironmentObject var viewRouter: ViewRouter
    
    @StateObject var recipe1 = recipe()
    
    var body: some View{
        ScrollView{
            VStack{
                HStack{
                    Button {
                        print("Going Back")
                        viewRouter.currentPage = .uploadView2
                    } label: {
                        Image(systemName: "arrow.left")
                            .font(.system(size: 30))
                            .foregroundColor(.black)
                    }
                    .padding(.horizontal)
                    Spacer()
                    Text("Add Instructions")
                        .font(.system(size: 30))
                        .fontWeight(.bold)
                    Spacer()
                    Button {
                        print("Saved")
                    } label: {
                        Image(systemName: "bookmark")
                            .font(.system(size: 30))
                            .foregroundColor(.black)
                    }
                    .padding()
                }
                Text("Add Instructions so that people can easily follow your recipe")
                    .padding()
                Button {
                    self.addData()
                } label: {
                    Label("next", systemImage: "arrow.right")
                }

            }
        }
        .environmentObject(recipe1)
    }
    
    func addData(){
        let db = Firestore.firestore()
        guard let uid = FirebaseManager.shared.auth.currentUser?.uid else{return}
        db.collection("Recipes").addDocument(data: ["id" : uid, "name" : recipe1.name, "dishType" : recipe1.dishType, "cuisine" : recipe1.cuisine, "difficulty" : recipe1.difficulty,"prepMins" : recipe1.prepMins, "prepHours": recipe1.prepHours, "cookMins" : recipe1.cookMins, "cookHours": recipe1.cookHours, "restMins" : recipe1.restMins, "restHours" : recipe1.restHours, "ingredients" : recipe1.ingredients])
        { err in
            if let err = err {
                print("Error writing document: \(err)")
            } else {
                print("Document successfully written!")
            }
        }

        
    }
}

struct UploadView3_Previews: PreviewProvider {
    static var previews: some View {
        UploadView3()
    }
}

如果有比使用环境对象更好的方法请告诉我,否则如何在我的视图之间传递数据?

非常感谢您的宝贵时间

你有两个独立的 @StateObject var recipe1 = recipe(),一个在 UploadViewUploadView3 中。所以当你在 UploadView3 中使用 func addData(){...} 时,你有一个新的空 recipe.

你应该只有一个,那就是单一的事实来源。然后使用 @ObservedObject var recipe1: recipe.environmentObject(recipe1)@EnvironmentObject var recipe1: recipe 传递它。