DrDev
DrDev

Reputation: 23

Segue after firebase download/upload completes

Im trying to run some code after firebase has finished its downloading/uploading (eg segue or refresh)

for eg

I have x3 save functions which all have code to update both storage and database of certain data (eg text and images)

save1()
save2()
save3()

when an IBAction is performed I would like these functions to run, and on completion if their is no error to perform another function on completion (segue or refresh)

these 3 save function currently work within the IBAction

@IBAction func saveTap(_ sender: Any) {

save1()
save2()
save3()

}

Save function as follows:

(I check if image has been changed, then upload process begins)

 func save1(){

    if image1.image == nil {
        let gender = userGender.text
        self.databaseRef.child("users").child(gender!).child(Auth.auth().currentUser!.uid).child("images").child("imageOne").removeValue { (error, ref) in
            if error != nil {
                print(error!)}
        }
        let imageRef = self.storage.child(Auth.auth().currentUser!.uid).child("image1")
        imageRef.delete { error in
            if let error = error {
                print(error)
            } else {
                print("Photo 1 image deleted")}
        }

    } else {

        //Firebase child references
        let profileImageRef = storage.child(Auth.auth().currentUser!.uid).child("image1")
        let metaData = StorageMetadata()
        metaData.contentType = "image1/jpeg"
        //Firebase child references

        //change uiimageview to uiimage for upload
        guard let image = image1.image else
        {return}
        //change uiimageview to uiimage for upload

        //Send to firebase storage
        profileImageRef.putData(image.jpegData(compressionQuality: 0.1)!, metadata: metaData) { (data, error) in
            if error == nil
            {print("Photo 1 uploaded to storage")}
            else
            {print(error?.localizedDescription as Any)}}
        //Send to firebase storage


        //Update firebase database
        profileImageRef.downloadURL(completion: { (url, error) in
            if error != nil{
                print(error!)
                return}

            if let profilePhotoUrl = url?.absoluteString{
                let newValuesForProfile = profilePhotoUrl
                let gender = self.userGender.text
                self.databaseRef.child("users").child(gender!).child(Auth.auth().currentUser!.uid).child("images").child("imageOne").setValue(newValuesForProfile, withCompletionBlock: { (error, ref) in
                    if error != nil{
                        print(error!)
                        return}
                    print("Photo 1 updated in database")})}})
        //Update firebase database
    }

I need the uploads to complete before the segues are performed as the next view will be refreshing to the saved data that i'm trying to upload.

any help would be great, been at this for weeks now :( iv tried completion handlers but no luck as of yet.

thank you in advance

Upvotes: 0

Views: 96

Answers (2)

Dris
Dris

Reputation: 844

You can check if the changes are saved with .childChanged somehow like this:

    save1()
    save2()
    save3()

let ref: DatabaseReference!
ref = /YourDirectDatabaseReferenceForTheChangedNode/
ref.observe(.childChanged, with: {(snaphost) -> Void in

    }
})

Maybe you should use UIActivityIndicatorView aswell to show something is going in the background.

@IBAction func saveTap(_ sender: Any) {

           save1()
           save2()
           save3()

        let activity: UIActivityIndicatorView = UIActivityIndicatorView()
            activity.center = self.view.center
            activity.hidesWhenStopped = true
            activity.activityIndicatorViewStyle = .whiteLarge
            self.view.addSubview(activity)

         let ref: DatabaseReference!
         ref = /YourDirectDatabaseReferenceForTheChangedNode/
         ref.observe(.childChanged, with: {(snaphost) -> Void in

           activity.stopAnimating()
           if UIApplication.shared.isIgnoringInteractionEvents {
              UIApplication.shared.endIgnoringInteractionEvents()
           }
        self.performSegue(withIdentifier: "backhome", sender: self)
        }
    })
 }

Replace /YourDirectDatabaseReferenceForTheChangedNode/ with the correct child (what should change after save).

Upvotes: 0

Shehata Gamal
Shehata Gamal

Reputation: 100503

I think dispatchGroup fits with your case

let dispatchGroup = DispatchGroup()

dispatchGroup.enter()
save1 { dispatchGroup.leave() }

dispatchGroup.enter()
save2 { dispatchGroup.leave() }



dispatchGroup.notify(queue: .main) {
  self.perFormSegue//////
}

//

// e.x structure

func save1(completion:@escaping()->()) {

  firesCallBack {       
   if success {
      completion()
   }
  }
}

Upvotes: 2

Related Questions