Search code examples
iosswiftgoogle-cloud-firestorequeuesemaphore

Delay of delete data into Firestore array field values through loop SWIFT


enter image description here

I am trying to delete all the cart items through a for loop like this:

func removeRelatedProductFromUserCart(selectArrayNodeIds: [String], completion: @escaping(Error?)->()) {
        let semaphore = DispatchSemaphore(value: 0)
        let serialQueue = DispatchQueue(label: "com.queue.Serial")
        
        serialQueue.async {
            for nodeId in selectArrayNodeIds {
                FirebaseManager.shared.removeProductFromUsersWishOrCartList(isForWishList: false, item: nodeId) { (error) in
                    completion(error)
                    semaphore.signal()
                }
                semaphore.wait()
            }
        }
    }

And Firebasemanager:

func removeProductFromUsersWishOrCartList(isForWishList: Bool, item: String?, completion: @escaping (Error?) -> ()) {
        let uid = UserDefaults.standard.string(forKey: "uid")!
        if isForWishList == true {
            Firestore.firestore().collection("user").document(uid).updateData([
                "wishList": FieldValue.arrayRemove([item!])
            ]) { (error) in
                completion(error)
            }
        } else {
            Firestore.firestore().collection("user").document(uid).updateData([
                "cart": FieldValue.arrayRemove([item!])
            ]) { (error) in
                completion(error)
            }
        }
    }

And then when I am trying to fetch the cart items from the same field, I am getting the updated list of cart items after a delay. I observed the delete process opening firebase console and what I have found is that the delete happens in console with a delay. But the error response (error == nill) doesn't wait till then in removeRelatedProductFromUserCart. So how can I wait till delete all cart items on Firestore and then load them?


Solution

  • 1- Firebase runs in a background thread so no need for

    let serialQueue = DispatchQueue(label: "com.queue.Serial")
    

    2- You need a DispatchGroup

    func removeRelatedProductFromUserCart(selectArrayNodeIds: [String], completion: @escaping(Bool)->()) {
    
               let g = DispatchGroup() 
                for nodeId in selectArrayNodeIds {
                     g.enter()
                     FirebaseManager.shared.removeProductFromUsersWishOrCartList(isForWishList: false, item: nodeId) { (error) in  
                       q.leave()
                    } 
                } 
             g.notify(queue:.main) {
                completion(true)
             }
    }