Firebase: Как очистить определенные данные из firebase, когда пользователь убивает приложение?

У меня есть приложение, которое использует 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

Который говорит:

Ваша реализация этого метода имеет примерно пять секунд для выполнения любых задач и возврата. Если метод не возвращается до истечения времени, система может полностью завершить процесс.

И на самом деле не требуется более 5 секунд, чтобы очистить это поле от базы огня.

Тот же код работает нормально, когда я открываю приложение.

Так что мой код работает нормально, но есть кое-что, чего мне не хватает, когда я убиваю приложение.

Спасибо за вашу помощь.

2 ответа

Решение

Лучший способ обеспечить очистку данных при отключении пользователя - использовать onDisconnect обработчики. Документация Firebase объясняет их, но вот простой пример того, как вы могли бы использовать его:

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

Когда этот код выполняется, инструкция отправляется на сервер, чтобы удалить узел, когда клиент отключается. Это означает, что он всегда будет работать, даже когда клиент (или даже телефон) выходит из строя, и ваш код на стороне клиента никогда не получает шанс выполнить.

Использование асинхронной задачи в applicationWillTerminat - не лучший подход, потому что у вас есть 5 секунд, чтобы убедиться, что асинхронная задача в зависимости от силы интернет-соединения должна завершить свое выполнение (для вас это может занять менее 5 секунд для обычного пользователя). это может занять больше), иначе процесс будет убит.

Как я уже упоминал в разделе комментариев, есть еще один случай, о котором вы даже не подумали, даже если получите эту работу:

если пользователь сначала переключает приложение в фоновый режим, а после этого пытается завершить приложение, applicationWillTerminate не будет вызываться.

вы пытаетесь что-то, что теоретически невозможно

Попробуйте подумать примерно так:

func applicationDidEnterBackground(_ application: UIApplication) {

     WebServiceAPI.checkOutVenue()
}
Другие вопросы по тегам