Reputation: 982
So on my first loading screen, I have the user sign in anonymously - so they have permission to access the Firebase database. Here is the code:
Auth.auth().signInAnonymously { (user, error) in
if error != nil {
print(error!.localizedDescription)
SVProgressHUD.showError(withStatus: AlertMessages.authError)
} else {
print("successfully signed in anon")
}
}
successfully signed in anon
prints out every time I run it, which is what should happen. But in my applicationWillTerminate
, I try to delete this anonymous user so there won't be any dangling users, but it doesn't work. Here is the code:
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
print("will terminate")
if Auth.auth().currentUser != nil {
print("user exists")
if (Auth.auth().currentUser?.isAnonymous)! {
print("delete anonymous user")
Auth.auth().currentUser?.delete(completion: { (error) in
if error != nil {
print(error!.localizedDescription)
try! Auth.auth().signOut()
} else {
print("delete success")
}
})
}
}
}
It prints out:
will terminate
user exists
delete anonymous user
Why is it that it never prints out the completion block?
Upvotes: 1
Views: 1330
Reputation: 7047
It looks like this is some what of a problem. The first question I have is why do you want to delete the user?
Looking at this answer you see that once an anonymous user's authentication token is removed / expired their account if forgotten by Firebase. This means that signing an anonymous user out of their account would remove that user. If the same user signed in anonymously again they would be provided a new token.
The documentation also states:
To protect your project from abuse, Firebase limits the number of new email/password and anonymous sign-ups that your application can have from the same IP address in a short period of time. You can request and schedule temporary changes to this quota from the Firebase console
If you're trying to delete accounts and the data associated with those accounts I'd take a look at this repo.
Looking at Authenticate with Firebase Anonymously and Delete a User documentation there is no mention of deleting an anonymous account. I think this is because signing them out is the same thing as deleting a real account. This is probably why calling Auth.auth().currentUser?.delete
seems to do nothing on an anonymous user.
Update
OP confirmed that you can delete an anonymous user. The above code placed inside applicationDidEnterBackground deletes the account. So the question is why doesn't the print statement appear when the code is placed inside applicationWillTerminate
.
Looking at 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.
This is probably why you aren't seeing the callback print statement. The app is terminated before that completion is returned. I'm not 100% sure how anonymous sign in works, but there should be other ways to verify the account was deleted.
After the application is terminated do you have to sign in again? If you do then the token was deleted.
Additionally, the app life cycle documentation states:
Apps must be prepared for termination to happen at any time and should not wait to save user data or perform other critical tasks. System-initiated termination is a normal part of an app’s life cycle. The system usually terminates apps so that it can reclaim memory and make room for other apps being launched by the user, but the system may also terminate apps that are misbehaving or not responding to events in a timely manner.
Suspended apps receive no notification when they are terminated; the system kills the process and reclaims the corresponding memory. If an app is currently running in the background and not suspended, the system calls the applicationWillTerminate: of its app delegate prior to termination. The system does not call this method when the device reboots.
In addition to the system terminating your app, the user can terminate your app explicitly using the multitasking UI. User-initiated termination has the same effect as terminating a suspended app. The app’s process is killed and no notification is sent to the app.
Since suspended apps do not receive an applicationWillTerminate
notification you might want to reconsider how you are doing things.
Upvotes: 0
Reputation: 4156
It is very strange. At first glance it seems that you are doing everything right.
Try this approach:
let user = Auth.auth().currentUser
user?.reauthenticate(with:credential) { error in
if let error = error {
showAlertWithErrorMessage(message: error.localizedDescription)
} else {
user?.delete { error in
if let error = error {
showAlertWithErrorMessage(message: error.localizedDescription)
} else {
let userID = HelperFunction.helper.FetchFromUserDefault(name: kUID)
Database.database().reference(fromURL: kFirebaseLink).child(kUser).child(userID).removeValue()
try! Auth.auth().signOut()
showAlertWithErrorMessage(message: "Your account deleted successfully...")
return
}
}
}
}
Upvotes: 0