AdamLeet
AdamLeet

Reputation: 227

Preview not working throwing error: Failed to get FirebaseApp instance. Please call FirebaseApp.configure() before using Firestore

My preview crashes with the error: Failed to get FirebaseApp instance. Please call FirebaseApp.configure() before using Firestore. My guess is it is because in ProfileViewController I try to access firebase and I configure firebase in an extra class that is not called before. Is there any workaround? I tried setting var Firebasemanager = FirebaseManager() in preview but it still fails.

This is the class where I call configure():

class FirebaseManager: NSObject {
    
    let auth: Auth
    let storage: Storage
    let firestore: Firestore
    
    var currentUser: ChatUser? // User?
    
    static let shared = FirebaseManager()
    
    override init() {
        FirebaseApp.configure()
        
        self.auth = Auth.auth()
        self.storage = Storage.storage()
        self.firestore = Firestore.firestore()
        
        super.init()
    }
}

This are all the States of my View:

    @Environment(\.presentationMode) var presentationMode
    @State var shouldShowImagePicker: Bool = false
    @State var loginStatusMessage = ""
    @EnvironmentObject var viewRouter: ViewRouter
    @StateObject var profileController = ProfileViewController()
    @ObservedObject var userViewModel = UserViewModel()

This is what my Preview looks like:

struct ProfileView_Previews: PreviewProvider {
    static var previews: some View {
        ProfileView(presentationMode: Environment(\.presentationMode), shouldShowImagePicker: false, loginStatusMessage: "", profileController: ProfileViewController(), userViewModel: UserViewModel()).environmentObject(ViewRouter())
    }
}

EDIT: This is the ProfileViewController:

class ProfileViewController: ObservableObject {
    let uid = FirebaseManager.shared.auth.currentUser?.uid ?? ""
    let store = FirebaseManager.shared.firestore
        
    func deleteCurrentTrack() async {
        try? await store.collection("current_track").document(uid).delete()
    }
}

This is where I call it in my ProfileView:

struct ProfileView: View {
   var body: some View {
      Button() {
         Task {
            await profileController.deleteCurrentTrack()
            try await FirebaseManager.shared.auth.currentUser?.delete()
} 
   } label: {
    Text("Delete track")
                    }
}
}

Upvotes: 0

Views: 439

Answers (1)

AdamLeet
AdamLeet

Reputation: 227

The reason my preview failed was because of UserViewModel.

At the top I set let db = Firestore.firestore(), deleting this solved the problem.

class UserViewModel: ObservableObject {
    
    let db = Firestore.firestore()
    
    @Published var chatUser: ChatUser?
    
    init() {
        fetchCurrentUser()
    }
    
    func fetchCurrentUser() {
        guard let uid = FirebaseManager.shared.auth.currentUser?.uid else {
            return
        }
        FirebaseManager.shared.firestore.collection("users").document(uid).getDocument { snapshot, error in
            if let error = error {
                print("Failed to fetch current user: ", error)
            }
            self.chatUser = try? snapshot?.data(as: ChatUser.self)
            FirebaseManager.shared.currentUser = self.chatUser
        }
    }
}

My Preview looks like this:

struct ProfileView_Previews: PreviewProvider {
    static var previews: some View {
        ProfileView().environmentObject(ViewRouter())
    }
}

Upvotes: 1

Related Questions