I got this error in my AppView : Fatal error: No ObservableObject of type GetData found. A View.environmentObject(_:) for GetData may be missing as an ancestor of this view.
I'm looking for a solution all days. How can I fix it?
FinalProjectApp.swift
import SwiftUI
import SwiftData
import Firebase
import FirebaseAuth
@main
struct FinalProjectApp: App {
@StateObject var data = AllDrinks()
@StateObject var gd = GetData()
init(){
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
if Auth.auth().currentUser != nil {
AppView()
.environmentObject(data)
.environmentObject(gd)
} else {
ContentView()
.environmentObject(data)
.environmentObject(gd)
}
}
}
}
AppView.swift
import SwiftUI
import FirebaseFirestore
import FirebaseFirestoreSwift
import FirebaseAuth
struct AppView: View{
@EnvironmentObject var data: AllDrinks
@EnvironmentObject var gd: GetData
@State var name: String?
init() {
UITabBar.appearance().backgroundColor = UIColor.wootea
if let user = Auth.auth().currentUser{
gd.user_name = user.displayName ?? ""
//gd.setName(name: (user.displayName ?? ""))
//gd.fav_path = "user/" + (user.displayName ?? "") + "/favorite"
//gd.order_path = "user/" + (user.displayName ?? "") + "/order"
print("AppView name:\(gd.user_name)")
//print("AppView fav_path:\(gd.fav_path)")
//print("AppView order_path:\(gd.order_path)")
}
}
var body: some View{
TabView{
HomeView()
.tabItem{
Label("", systemImage: "house")
}
// FavoriteView()
// .tabItem{
// Label("", systemImage: "heart")
// }
// OrderView()
// .tabItem{
// Label("", systemImage: "cart")
// }
// AccountView()
// .tabItem{
// Label("", systemImage: "person")
// }
}
.tabViewStyle(DefaultTabViewStyle())
.environmentObject(data)
.environmentObject(gd)
}
}
struct AppView_Previews: PreviewProvider {
static var previews: some View {
AppView()
.environmentObject(AllDrinks())
.environmentObject(GetData())
}
}
ContentView.swift
import SwiftUI
import SwiftData
import FirebaseAuth
struct ContentView: View {
@State private var email = ""
@State private var password = ""
@State private var alertTitle = ""
@State private var showAlert = false
@State var showBool = false
@EnvironmentObject var gd: GetData
@EnvironmentObject var data: AllDrinks
var body: some View {
NavigationStack{
ZStack{
VStack{
Color(.white)
.ignoresSafeArea()
Color(.orange)
.ignoresSafeArea()
}
VStack{
Image("logo")
.resizable()
.scaledToFill()
.frame(width: 400, height: 400)
Spacer()
Group{
TextField("Email", text: $email, prompt: Text("Email"))
.textFieldStyle(.roundedBorder)
.padding()
SecureField("Password", text: $password)
.textFieldStyle(.roundedBorder)
.padding()
}
.font(Font.system(size: 25, design: .default))
Spacer()
HStack(spacing: 30){
Button{
login()
} label: {
Text("Login")
.foregroundColor(.white)
.font(.title2)
.fontWeight(.semibold)
}
.padding()
.background(Color.black)
.cornerRadius(40)
.fullScreenCover(isPresented: $showBool){
AppView()
}
.alert(alertTitle, isPresented: $showAlert){
Button("OK"){}
} message: {
Text("")
}
NavigationLink {
SignUpView()
} label: {
Text("Sign Up")
.foregroundColor(.black)
.font(.title2)
.fontWeight(.semibold)
}
.padding()
.background(Color.white)
.cornerRadius(40)
}
} // vstack
} // zstack
} // nav
.environmentObject(gd)
.environmentObject(data)
} // body
func login(){
Auth.auth().signIn(withEmail: email, password: password){ result, error in
guard error == nil else {
if let message = error?.localizedDescription {
alertTitle = message
}
showAlert = true
return
}
if let user = Auth.auth().currentUser{
gd.user_name = user.displayName ?? ""
gd.fav_path = "user/" + (user.displayName ?? "") + "/favorite"
gd.order_path = "user/" + (user.displayName ?? "") + "/order"
print("ContentView name:\(gd.user_name)")
print("ContentView fav_path:\(gd.fav_path)")
print("CintentView order_path:\(gd.order_path)")
}
alertTitle = "success"
showBool = true
}
}
}
struct ContentView_Previews: PreviewProvider{
static var previews: some View{
ContentView()
.environmentObject(GetData())
.environmentObject(AllDrinks())
}
}
Drink.swift
import Foundation
import FirebaseFirestore
import FirebaseFirestoreSwift
import FirebaseAuth
class GetData: ObservableObject {
@Published var user_name: String = ""
@Published var fav_path: String = ""
@Published var order_path: String = ""
func getName() -> String{
if let user = Auth.auth().currentUser{
user_name = user.displayName ?? ""
if user_name != nil{
print("User:\(user_name)")
}
}
return user_name
}
func setName(name:String){
user_name = name;
}
func getFavpath() -> String{
var name = getName()
fav_path = "user/" + name + "/favorite"
return fav_path
}
func getOrderpath() -> String{
var name = getName()
order_path = "user/" + name + "/order"
return order_path
}
}
class AllDrinks: ObservableObject{
@Published var allDrinks = [Drink]()
@Published var orders = [Drink]()
@Published var total = 0
func calTotal(){
total = 0
for i in orders.indices{
total += orders[i].price
}
}
// clear placed orders
func removeOrder(){
orders.removeAll()
total = 0
}
// update all drink data
func createDrink(drink: Drink){
let db = Firestore.firestore()
do{
try db.collection("drink").document("\(drink.name)").setData(from: drink)
} catch {
print(error)
}
}
/*
// update my favorite drink data
func updateFavoriate() {
for drink in allDrinks{
createDrink(drink: drink)
}
}
*/
// revise favorite data
func modifyFavorite(fav: Favorite, id: String) {
let db = Firestore.firestore()
do{
if let user = Auth.auth().currentUser{
var user_name: String? = user.displayName
if user_name != nil{
try db.collection("user").document(user_name ?? "").collection("favorite").document(id).setData(from: fav)
print("modifyFavorite Success")
}
}
} catch {
print(error)
}
}
}
struct Drink: Codable, Identifiable{
var name: String
var description: String
var Mprice: Int
var Lprice: Int
var hasHot: Bool = true
var isFavorite: Bool = false
var type: String
@DocumentID var id: String?
var size: String = "M"
var ice: String = "Normal"
var sugar: String = "Normal"
var price: Int = 0
}
struct Favorite: Codable, Identifiable{
var name: String
@DocumentID var id: String?
}