Firebase:当用户终止应用程序时如何从 Firebase 中清除特定数据?

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

我有一个使用 firebase 作为数据库的应用程序,我想在用户终止该应用程序时清除名为 current_venue 的特定用户字段,为此我正在使用 AppDelegate 方法 applicationWillTerminate 和当我杀死应用程序时它实际上正在调用,但没有完全。

下面是我在 AppDelegate 中的代码:

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

另一种方法是:

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 = ""
        }
    }
}

我试着调试它,如下图所示:

当我终止应用程序时,断点 1 和 2 正在调用,但它从未到达断点 3。

我阅读了文档:

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

上面写着:

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.

实际上,从 firebase 中清除该字段所用的时间不会超过 5 秒。

当我打开应用程序时,相同的代码运行正常。

所以我的代码工作正常,但是当我终止应用程序时我遗漏了一些东西。

感谢您的帮助。

在 applicationWillTerminat 中设置异步任务不是最佳方法,因为您有 5 秒的时间来确保异步任务取决于互联网连接的强度 应该完成它的执行(对于你来说这可能需要不到 5 秒对于普通用户这可能需要更多),否则进程将被杀死。

正如我在评论部分提到的,还有另一种情况,即使你得到了这份工作,你也没有想到:

如果用户首先将应用程序切换到后台,然后尝试终止应用程序,则不会调用 applicationWillTerminate。

你正在尝试理论上不可能的事情

试着这样想:

func applicationDidEnterBackground(_ application: UIApplication) {

     WebServiceAPI.checkOutVenue()
}

确保在用户断开连接时清除数据的更好方法是使用 onDisconnect 处理程序。 Firebase documentation explains them,但这里有一个如何使用它的简单示例:

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

当这段代码执行时,指令发送到服务器端,在客户端断开连接时移除节点。这意味着它将始终 运行,即使客户端(甚至 phone)崩溃并且您的客户端代码永远没有机会执行。