I get this Error -> Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) randomly. I don't quite understand when exactly it happens. Most of the times it is when the view refreshes. The Error appears at the line where group.leave() gets executed.
What am I trying to do: I want to fetch albums with their image, name and songs that also have a name and image from my firebase database. I checked for the values and they're all right as far as I can tell. But when trying to show them it is random what shows. Sometimes everything is right, sometimes one album gets showed twice, sometimes only one album gets showed at all, sometimes one album has the songs of the other album.
My firebase database has albums stored as documents, each document has albumimage/name and 2 subcollections of "unlocked" with documents(user uid) that store "locked":Bool and "songs" with a document for each song that stores image/name 
This is the function that fetches my albums with their songs:
let group = DispatchGroup() @State var albums: [Album] = [] @State var albumSongs: [AlbumSong] = [] func fetchAlbums() { FirebaseManager.shared.firestore.collection("albums").getDocuments { querySnapshot, error in if let error = error { print(error.localizedDescription) return } guard let documents = querySnapshot?.documents else { return } let uid = FirebaseManager.shared.auth.currentUser?.uid documents.forEach { document in let data = document.data() let name = data["name"] as? String ?? "" let artist = data["artist"] as? String ?? "" let releaseDate = data["releaseDate"] as? Date ?? Date() let price = data["price"] as? Int ?? 0 let albumImageUrl = data["albumImageUrl"] as? String ?? "" let docID = document.documentID FirebaseManager.shared.firestore.collection("albums").document(docID) .collection("songs").getDocuments { querySnapshot, error in if let error = error { return } guard let documents = querySnapshot?.documents else { return } self.albumSongs = documents.compactMap { document -> AlbumSong? in do { return try document.data(as: AlbumSong.self) } catch { return nil } } group.leave() } FirebaseManager.shared.firestore.collection("albums").document(docID) .collection("unlocked").document(uid ?? "").getDocument { docSnapshot, error in if let error = error { return } guard let document = docSnapshot?.data() else { return } group.enter() group.notify(queue: DispatchQueue.global()) { if document["locked"] as! Bool == true { self.albums.append(Album(name: name, artist: artist, songs: albumSongs, releaseDate: releaseDate, price: price, albumImageUrl: albumImageUrl)) print("albums: ",albums) } } } } } } I call my fetchAlbums() in my view .onAppear()
My AlbumSong:
struct AlbumSong: Identifiable, Codable { @DocumentID var id: String? = UUID().uuidString let title: String let duration: TimeInterval var image: String let artist: String let track: String } My Album:
struct Album: Identifiable, Codable { @DocumentID var id: String? = UUID().uuidString let name: String let artist: String let songs: [AlbumSong] let releaseDate: Date let price: Int let albumImageUrl: String } I tried looking into how to fetch data from firebase with async function but I couldn't get my code to work and using dispatchGroup worked fine when I only have one album. I would appreciate answers explaining how this code would work with async, I really tried my best figuring it out by myself a long time. Also I would love to know what exactly is happening with DispatchGroup and why it works fine having one album but not with multiple ones.
DispatchGroupis wrong. inside the loop before calling the asynchronous task callenterand inside the completion handler callleave. And it's crucial sure that callingenterandleaveis balanced.