Dharmesh Kheni
Dharmesh Kheni

Reputation: 71852

Firebase: How to clear specific data from firebase when user kill app?

I have app which uses firebase for database and I want to clear specific user field called current_venue when user kill the app and for that I am using AppDelegate method applicationWillTerminate and it's actually calling when I kill the app but not completely.

Below is my code in AppDelegate:

func applicationWillTerminate(_ application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    WebServiceAPI.checkOutVenue()
}

And another method is:

static func checkOutVenue() {

    WebServiceAPI.sharedInstance.current_venue = ""
    if WebServiceAPI.sharedInstance.user == nil {
        return
    }
    let user = WebServiceAPI.sharedInstance.user!
    let ref = FIRDatabase.database().reference()
    ref.child("Clients").child(user.uid).child("current_venue").setValue("") { (err, venueIdRef) in
        if err == nil {
            WebServiceAPI.sharedInstance.current_venue = ""
        }
    }
}

And I tried to debug it something like below image:

enter image description here

When I kill app breakpoint 1 and 2 is calling but its never reaching at breakpoint 3.

I read the documentation from:

https://developer.apple.com/reference/uikit/uiapplicationdelegate/1623111-applicationwillterminate

Which says:

Your implementation of this method has approximately five seconds to perform any tasks and return. If the method does not return before time expires, the system may kill the process altogether.

And Actually its not taking more than 5 seconds to clear that field from firebase.

Same code is working fine when I open the app.

So my code is working fine but there is something which I am missing when I am killing the app.

Thanks for your help.

Upvotes: 1

Views: 1425

Answers (2)

Frank van Puffelen
Frank van Puffelen

Reputation: 599956

A better way to ensure data is cleaned up when the user disconnects is to use onDisconnect handlers. The Firebase documentation explains them, but here's a simple example of how you'd use it:

ref.child("Clients")
   .child(user.uid)
   .child("current_venue")
   .onDisconnectRemoveValue()

When this code executes, the instruction is sent to the server to remove the node when the client disconnects. That means that it will always run, even when the client (or even the phone) crashes and your client-side code never gets a chance to execute.

Upvotes: 4

Achref Gassoumi
Achref Gassoumi

Reputation: 1056

Having an async task in applicationWillTerminat is not the best approach, because you have 5 sec to make sure that an async task depending on the strength of the internet connection should finish its execution (for you this maybe take less than 5 sec for a normal user this could take more) , otherwise the process will get killed.

As i mentioned in the comment section there is another case you didn't think about even if you get this work :

if user switch app to background at first, and after this try terminate app, applicationWillTerminate will not called.

you are trying something which is theoretically impossible

Try to think about something like this:

func applicationDidEnterBackground(_ application: UIApplication) {

     WebServiceAPI.checkOutVenue()
}

Upvotes: 2

Related Questions