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()
,一个在 UploadView
和 UploadView3
中。所以当你在 UploadView3
中使用 func addData(){...}
时,你有一个新的空 recipe
.
你应该只有一个,那就是单一的事实来源。然后使用
@ObservedObject var recipe1: recipe
或 .environmentObject(recipe1)
和 @EnvironmentObject var recipe1: recipe
传递它。
我正在尝试制作一个简单的应用程序,让用户可以创建食谱,然后将它们上传到 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()
,一个在 UploadView
和 UploadView3
中。所以当你在 UploadView3
中使用 func addData(){...}
时,你有一个新的空 recipe
.
你应该只有一个,那就是单一的事实来源。然后使用
@ObservedObject var recipe1: recipe
或 .environmentObject(recipe1)
和 @EnvironmentObject var recipe1: recipe
传递它。