Наблюдаемый объект типа не найден после выхода из системы

#ios #swift #swiftui

Вопрос:

В настоящее время я пытаюсь создать приложение, которое извлекает данные из Firebase, и у меня возникли некоторые проблемы. Я пытаюсь создать карточку профиля, в которой будут отображаться некоторые данные, прикрепленные к user.uid, но как только я выхожу из системы и снова вхожу, я получаю сообщение об ошибке:

 Fatal error: No ObservableObject of type UserDataManager found. A View.environmentObject(_:) for UserDataManager may be missing as an ancestor of this view.
 

Файл Приложения:

 import SwiftUI
import Firebase

@main
struct Darbo_ManijaApp: App {

@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

var body: some Scene {
    WindowGroup {
        let viewModel = AppViewModel()
        let userdataManager = UserDataManager()
        ContentView()
            .environmentObject(viewModel)
            .environmentObject(userdataManager)
    }
}
}

class AppDelegate: NSObject, UIApplicationDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    FirebaseApp.configure()
    return true
}

}
 

Файл UserDataManager:

 import Foundation
import Firebase

class UserDataManager: ObservableObject {

@Published var userFirstName: String = ""

init() {
    fetchUser()
}

func fetchUser() {
    let db = Firestore.firestore()
    let userID = Auth.auth().currentUser?.uid ?? "Not Found"
    
    db.collection("users").document(userID)
        .addSnapshotListener { documentSnapshot, error in
            guard let document = documentSnapshot else {
                print("Error fetching document: (error!)")
                return
            }
            
            guard let data = document.data() else {
                print("Document data was empty.")
                return
            }
            print("Fetched Data")
            self.userFirstName = data["firstname"] as? String ?? ""
        }
}
}
 

ContentView File:

 struct ContentView: View {

@EnvironmentObject var userdataManager: UserDataManager
@EnvironmentObject var viewModel : AppViewModel
var body: some View {
    if viewModel.isSignedIn {
        
        UIKitTabView {
            JobListView().environmentObject(userdataManager).environmentObject(viewModel).tab(title: "Pradžia", image: "network")
            JobListView().tab(title: "Žinutės", image: "message")
            LoginView().tab(title: "Paskyra", image: "person")
            
        }
    } else {
        LoginView()
    }
}
}
 

And the JobsList view:

 struct JobListView: View {

@EnvironmentObject var viewModel : AppViewModel
@EnvironmentObject var userdataManager: UserDataManager
let firebaseUserID = Auth.auth().currentUser?.uid ?? "Not Found"

var body: some View {
    
    NavigationView{
        ScrollView{
            VStack(alignment: .leading, spacing: 0) {
                Text("Test")
                Text("User ID is: (firebaseUserID)")
                
                Text("My Name is: (userdataManager.userFirstName)")

                ForEach(jobData, id: .id) { job in
                    JobCardView(job: job)
                }
            }
            .frame(minWidth: 0,
                   maxWidth: .infinity,
                   minHeight: 0,
                   maxHeight: .infinity)
            .padding()
        }
        .navigationBarItems(leading:
                                HStack{
            Image("TextDM")
                .resizable()
                .scaledToFit()
                .frame(height: 15)
        })
        .navigationBarItems(trailing:
                                HStack{
            
            Button(action: {
                viewModel.signOut()
            }) {
                Image(systemName: "person.crop.circle")
                    .accentColor(Color.primary)
                
            }
        })
        
        .navigationBarTitle("")
        .navigationBarTitleDisplayMode(.inline)
        .onAppear(){
            userdataManager.fetchUser()
        }
    }
    .environmentObject(userdataManager)
    .environmentObject(viewModel)
}
}
 

Сначала я подумал, что это может быть проблемой, потому что в представлении содержимого при вызове элемента tabbaritem объект не задан, но, несмотря на то, что я это сделал, проблема остается. Как я уже упоминал, я получаю сообщение об ошибке на JobListView файл, где я использую текст(«мое имя: (userdataManager.userFirstName)») в первый раз приложение запускается, и если я вошел в систему, нет и ошибки .onAppear с объектами работы, а также выхода из системы, но когда я выйти из системы и снова войти в систему, я получаю выше сообщение об ошибке. Есть какие-либо предложения или советы о том, как это исправить?
Заранее спасибо!

ПРАВКА: Проблема решена. Проблема заключалась в том, что я использовал другое представление вкладок, которое должно было включать объекты ObservableObjects в каждую ссылку на вкладку. Спасибо за помощь!

Ответ №1:

Я не могу воспроизвести проблему с помощью моей текущей установки, но есть несколько вещей, которые я сделал бы по-другому в вашем коде.

в «Darbo_ManijaApp» поместите их за пределы «тела»

 let viewModel = AppViewModel()
let userdataManager = UserDataManager()
 

Убедитесь, что в «Представлении содержимого» последовательность @EnvironmentObject сначала «AppViewModel», а затем «UserDataManager».

что важно, также проходите

 .environmentObject(userdataManager).environmentObject(viewModel) 
 

к другому «Просмотр вакансий ()».
И еще раз убедитесь, что последовательность @EnvironmentObject верна.

Комментарии:

1. Спасибо за ответ! Я попробовал то, что вы предложили, но теперь я получаю следующую ошибку: ** «Экземпляр FirebaseApp по умолчанию должен быть настроен, прежде чем можно будет инициализировать аутентификацию по умолчанию. Один из способов убедиться в этом-вызвать FirebaseApp.configure() делегата приложения application(_:didFinishLaunchingWithOptions:) (или инициализатор @main структуры в SwiftUI)».**