Learn Courses My Dashboard

@Published Reseting

Hi,
I have this code, and when I run fetchData and then call Published variables via ObservedObject, the arrays come back as empty. Please help!

Code
class firebase1: ObservableObject {
    @Published var yesRestaurants: [Restaurants] = []
    @Published var allRestaurants: [AllRestaurants] = []
    @Published var yesMedia: [Media] = []
    @Published var allMedia: [AllMedia] = []
    @Published var devicesDone = Array<String>()
    
    private var allRestCount = 0
    private let db = Firestore.firestore()
    @Published var devices = Array<String>()
    static func fetchData(completion: @escaping (_ yesRestaurant: Array<Restaurants>, _ AllRestaurants: Array<AllRestaurants>, _ yesMedia: Array<Media>, _ allMedia: Array<AllMedia>, _ devices: Array<String>, _ devicesDone: Array<String>) -> Void) {
        let db = Firestore.firestore()
        print("Start Firebase Data Fetch")
        var yesRestaurants: [Restaurants] = []
        var allRestNames = Array<String>()
        var allRestaurants: [AllRestaurants] = []
        var yesMedia: [Media] = []
        var allMedia: [AllMedia] = []
        var devicesDone = Array<String>()
        var devices = Array<String>()
        func complete() {
//            allRestCount = 0
            Devices.correctList()
            print("done from func, yesRest = \(yesRestaurants), allRest = \(allRestaurants), yesMedia = \(yesMedia), yesRest = \(allMedia)")
            completion(yesRestaurants, allRestaurants, yesMedia, allMedia, devices, devicesDone)
        }
//        yesRestaurants.removeAll()
//        allRestaurants.removeAll()
//        devicesDone.removeAll()
        func getYesItems(yesItems: Array<String>) {
            for item in yesItems {
                print("item = \(item)")
                db.collection("parties").document(Utilities.code).collection("Items").document(item).addSnapshotListener { doc, error in
                    if error == nil && doc!.exists {
                        if Utilities.picktType == .media {
                            if let name = doc!.get("name") as? String {
                                if let img = doc!.get("img") as? String {
                                    if let id = doc!.get("id") as? String {
                                        if let rating = doc!.get("rating") as? Double {
                                            if let yes = doc!.get("yes") as? Array<String> {
                                                if let description = doc!.get("description") as? String {
                                                    if let tag = doc!.get("tag") as? Array<String> {
                                                        if let ratingCount = doc!.get("ratingCount") as? Int {
                                                            
                                                            print("media = \(AllMedia(name: name, imageUrl: URL(string: img)!, id: id, rating: rating, description: description, yes: yes, tag: tag, ratingCount: ratingCount))")
                                                            print("yes = \(yes), devices = \(devices)")
                                                            allMedia.append(AllMedia(name: name, imageUrl: URL(string: img)!, id: id, rating: rating, description: description, yes: yes, tag: tag, ratingCount: ratingCount))
                                                            if yes.sorted() == devices.sorted() {
                                                                yesMedia.append(Media(name: name, imageUrl: URL(string: img)!, id: id, description: description, ratingCount: ratingCount, rating: rating, tag: tag))
                                                            }
                                                            if yesItems.count == allRestaurants.count {
                                                                complete()
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }else {
                            if let name = doc!.get("name") as? String {
//                                print("item name = \(name)")
                                if var img = doc!.get("img") as? String {
                                    if img == "" {
                                        img = Utilities.noImage
                                    }
//                                    print("item img = \(img)")
                                    if let id = doc!.get("id") as? String {
//                                        print("item id = \(id)")
                                        if let rating = doc!.get("rating") as? Double {
//                                            print("item rating = \(rating)")
                                            if let url = doc!.get("url") as? String {
//                                                print("item url = \(url)")
                                                if let loc = doc!.get("location") as? String {
//                                                    print("item loc = \(loc)")
                                                    if let cat = doc!.get("category") as? Array<String> {
//                                                        print("item category = \(cat)")
                                                        if let yes = doc!.get("yes") as? Array<String> {
//                                                            print("item yes = \(yes)")
                                                                if let reviewCount = doc!.get("reviewCount") as? Int {
//                                                                    print("item reviewCount = \(reviewCount)")
                                                                    if let price = doc!.get("price") as? String {
//                                                                        print("item price = \(price)")
                                                                        if let isClosed = doc!.get("isClosed") as? Bool {
                                                                            if let tag = doc!.get("tag") as? Array<String> {
//                                                                                print("item tag = \(tag)")
                                                                            
//                                                                            print("item isClosed = \(isClosed)")
                                                                            print("yes = \(yes), devices = \(devices)")
                                                                            print("done allRestaurant \(allRestaurants.count + 1)")
//                                                                            allRestCount += yes.count
                                                                            print("compiled = name: \(name), imageUrl: \(URL(string: img)!), id: \(id), rating: \(rating), url: \(url), location: \(loc), category: \(cat), yes: \(yes), tag: \(tag), isClosed: \(isClosed), price: \(price), reviewCount: \(reviewCount)")
                                                                                allRestNames.append(name)
                                                                            allRestaurants.append(AllRestaurants(name: name, imageUrl: URL(string: img )!, id: id, rating: rating, url: url, location: loc, category: cat, yes: yes, tag: tag, isClosed: isClosed, price: price, reviewCount: reviewCount))
                                                                            if yes.sorted() == devices.sorted() {
                                                                                yesRestaurants.append(Restaurants(name: name, imageUrl: URL(string: img)!, id: id, rating: rating, url: url, location: loc, category: cat, tag: tag, isClosed: isClosed, price: price, reviewCount: reviewCount))
                                                                            }
                                                                                print("yesItems.count = \(yesItems.count), allRestaurants.count = \(allRestaurants.count)")
                                                                                
                                                                                if yesItems.count == allRestaurants.count {
                                                                                complete()
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        db.collection("parties").document(Utilities.code).addSnapshotListener { doc, error in
            if error == nil {
                if doc != nil && doc!.exists {
                    if let getDevices = doc!.get("devices") as? Array<String> {
                        devices = getDevices
                    }
                    if let devDone = doc!.get("devicesDone") as? Array<String> {
                        devicesDone = devDone
                    }
                }
            }
        }
        db.collection("parties").document(Utilities.code).addSnapshotListener { doc, error in
            if error == nil {
                if doc != nil && doc!.exists {
                    if let yesItems = doc!.get("yesItems") as? Array<String> {
                        print("yesItems = \(yesItems)")
                        getYesItems(yesItems: yesItems)
                    }
                }
            }
        }
    }
}

I can’t say for sure without being able to run your code (which I obviously can’t since this is only a small slice of it and I also don’t have your Firestore set up), but I imagine the fact that you are shadowing your @Published variables within the fetchData function could be the culprit.

By “shadowing” I mean that, for instance you have

@Published var yesMedia: [Media] = []

at the root of your ObservableObject but you also have

var yesMedia: [Media] = []

within your function. So if you assign to yesMedia in the function, it won’t get assigned to the yesMedia that is marked @Published but rather to the yesMedia that is local to the function. Make sense?

You solve this by either a) renaming your function variables (and then you have to remember to assign their value to the @Published class properties before the function exits, or b) forgo local variables entirely and just assign directly to the @Published class properties.


And just a word of advice: Clean up those nasty pyramids of doom you’ve got going on there. You should never have that many nested if statements.

Ok thx

It’s still not working.

New Code
class firebase1: ObservableObject {
    @Published var yesRestaurants: [Restaurants] = []
    @Published var allRestaurants: [AllRestaurants] = []
    @Published var yesMedia: [Media] = []
    @Published var allMedia: [AllMedia] = []
    @Published var devicesDone = Array<String>()
    
    private var allRestCount = 0
    private let db = Firestore.firestore()
    @Published var devices = Array<String>()
    static let shared = firebase1()
    func fetchData(completion: @escaping () -> Void) {//_ yesRestaurant: Array<Restaurants>, _ AllRestaurants: Array<AllRestaurants>, _ yesMedia: Array<Media>, _ allMedia: Array<AllMedia>, _ devices: Array<String>, _ devicesDone: Array<String>) -> Void) {
        let db = Firestore.firestore()
        print("Start Firebase Data Fetch")
//        var yesRestaurants: [Restaurants] = []
        var allRestNames = Array<String>()
//        var allRestaurants: [AllRestaurants] = []
//        var yesMedia: [Media] = []
//        var allMedia: [AllMedia] = []
//        var devicesDone = Array<String>()
//        var devices = Array<String>()
        func complete() {
//            allRestCount = 0
            Devices.correctList()
            print("done from func, yesRest = \(yesRestaurants), allRest = \(allRestaurants), yesMedia = \(yesMedia), yesRest = \(allMedia)")
            completion()//yesRestaurants, allRestaurants, yesMedia, allMedia, devices, devicesDone)
        }
//        yesRestaurants.removeAll()
//        allRestaurants.removeAll()
//        devicesDone.removeAll()
        func getYesItems(yesItems: Array<String>) {
            for item in yesItems {
                print("item = \(item)")
                db.collection("parties").document(Utilities.code).collection("Items").document(item).addSnapshotListener { doc, error in
                    if error == nil && doc!.exists {
                        if Utilities.picktType == .media {
                            if let name = doc!.get("name") as? String {
                                if let img = doc!.get("img") as? String {
                                    if let id = doc!.get("id") as? String {
                                        if let rating = doc!.get("rating") as? Double {
                                            if let yes = doc!.get("yes") as? Array<String> {
                                                if let description = doc!.get("description") as? String {
                                                    if let tag = doc!.get("tag") as? Array<String> {
                                                        if let ratingCount = doc!.get("ratingCount") as? Int {
                                                            
                                                            print("media = \(AllMedia(name: name, imageUrl: URL(string: img)!, id: id, rating: rating, description: description, yes: yes, tag: tag, ratingCount: ratingCount))")
                                                            print("yes = \(yes), devices = \(self.devices)")
                                                            self.allMedia.append(AllMedia(name: name, imageUrl: URL(string: img)!, id: id, rating: rating, description: description, yes: yes, tag: tag, ratingCount: ratingCount))
                                                            if yes.sorted() == self.devices.sorted() {
                                                                self.yesMedia.append(Media(name: name, imageUrl: URL(string: img)!, id: id, description: description, ratingCount: ratingCount, rating: rating, tag: tag))
                                                            }
                                                            if yesItems.count == self.allRestaurants.count {
                                                                complete()
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }else {
                            if let name = doc!.get("name") as? String {
//                                print("item name = \(name)")
                                if var img = doc!.get("img") as? String {
                                    if img == "" {
                                        img = Utilities.noImage
                                    }
//                                    print("item img = \(img)")
                                    if let id = doc!.get("id") as? String {
//                                        print("item id = \(id)")
                                        if let rating = doc!.get("rating") as? Double {
//                                            print("item rating = \(rating)")
                                            if let url = doc!.get("url") as? String {
//                                                print("item url = \(url)")
                                                if let loc = doc!.get("location") as? String {
//                                                    print("item loc = \(loc)")
                                                    if let cat = doc!.get("category") as? Array<String> {
//                                                        print("item category = \(cat)")
                                                        if let yes = doc!.get("yes") as? Array<String> {
//                                                            print("item yes = \(yes)")
                                                                if let reviewCount = doc!.get("reviewCount") as? Int {
//                                                                    print("item reviewCount = \(reviewCount)")
                                                                    if let price = doc!.get("price") as? String {
//                                                                        print("item price = \(price)")
                                                                        if let isClosed = doc!.get("isClosed") as? Bool {
                                                                            if let tag = doc!.get("tag") as? Array<String> {
//                                                                                print("item tag = \(tag)")
                                                                            
//                                                                            print("item isClosed = \(isClosed)")
                                                                                print("yes = \(yes), devices = \(self.devices)")
                                                                                print("done allRestaurant \(self.allRestaurants.count + 1)")
//                                                                            allRestCount += yes.count
                                                                            print("compiled = name: \(name), imageUrl: \(URL(string: img)!), id: \(id), rating: \(rating), url: \(url), location: \(loc), category: \(cat), yes: \(yes), tag: \(tag), isClosed: \(isClosed), price: \(price), reviewCount: \(reviewCount)")
                                                                                allRestNames.append(name)
                                                                                self.allRestaurants.append(AllRestaurants(name: name, imageUrl: URL(string: img )!, id: id, rating: rating, url: url, location: loc, category: cat, yes: yes, tag: tag, isClosed: isClosed, price: price, reviewCount: reviewCount))
                                                                                if yes.sorted() == self.devices.sorted() {
                                                                                    self.yesRestaurants.append(Restaurants(name: name, imageUrl: URL(string: img)!, id: id, rating: rating, url: url, location: loc, category: cat, tag: tag, isClosed: isClosed, price: price, reviewCount: reviewCount))
                                                                            }
                                                                                print("yesItems.count = \(yesItems.count), allRestaurants.count = \(self.allRestaurants.count)")
                                                                                
                                                                                if yesItems.count == self.allRestaurants.count {
                                                                                complete()
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        db.collection("parties").document(Utilities.code).addSnapshotListener { doc, error in
            if error == nil {
                if doc != nil && doc!.exists {
                    if let getDevices = doc!.get("devices") as? Array<String> {
                        self.devices = getDevices
                    }
                    if let devDone = doc!.get("devicesDone") as? Array<String> {
                        self.devicesDone = devDone
                    }
                }
            }
        }
        db.collection("parties").document(Utilities.code).addSnapshotListener { doc, error in
            if error == nil {
                if doc != nil && doc!.exists {
                    if let yesItems = doc!.get("yesItems") as? Array<String> {
                        print("yesItems = \(yesItems)")
                        getYesItems(yesItems: yesItems)
                    }
                }
            }
        }
    }
}

Update @roosterboy: I had forgotten to add @StateObject to my scene delegate. Unfortunately, I use .fullScreenCover to show this view and am getting this error in my scene delegate:

Accessing StateObject's object without being installed on a View. This will create a new instance each time