Reputation: 2274
Inside my app the user
should be able to delete the account. I am struggling to get that done, as I have to delete from database and also from authentication.
I thought I can deleteFromAuthentication
first and after that I deleteEntryFromDatabase
. Theses are both of the functions:
//MARK: deleteUserFromDatabase
static func deleteUserEntryFromDatabase(oldUserId: String, finished: @escaping (_ done: Bool) -> Void) {
Auth.auth().signInAnonymously() { (authResult, error) in
let db = Firestore.firestore()
db.collection("users").document(oldUserId).delete() { err in
if err != nil {
Utilities.showErrorPopUp(labelContent: "Fehler", description: err!.localizedDescription)
finished(false)
} else {
finished(true)
}
}
}
}
//MARK: deleteUserFromAuthentication
static func deleteUserFromAuthentication(finished: @escaping (_ done: Bool, _ hasToReauthenticate: Bool) -> Void) {
let user = Auth.auth().currentUser
user?.delete { err in
if err != nil {
if let errCode = AuthErrorCode(rawValue: err!._code) {
switch errCode {
case .requiresRecentLogin:
finished(true, true)
default:
Utilities.showErrorPopUp(labelContent: "Fehler", description: err!.localizedDescription)
finished(false, false)
}
}
} else {
finished(true, false)
}
}
}
How I use them:
func deleteAccount() {
var uid = ""
if let defaults = UserDefaults(suiteName: UserDefaults.Keys.groupKey) {
uid = defaults.getUid()!
defaults.synchronize()
}
DataHandler.deleteUserFromAuthentication { (finished, hasToReauthenticate) in
if finished {
if hasToReauthenticate {
self.showReauthenticationAlert()
} else {
DataHandler.deleteUserEntryFromDatabase(oldUserId: uid) { (finished) in
if finished {
let firstLaunchVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "FirstLaunchVC")
self.navigationController?.pushViewController(firstLaunchVC, animated: false)
if let defaults = UserDefaults(suiteName: UserDefaults.Keys.groupKey) {
defaults.removePersistentDomain(forName: UserDefaults.Keys.groupKey)
defaults.synchronize()
}
} else {
self.loadingFailed()
}
}
}
} else {
self.loadingFailed()
}
}
}
However this is not working as I get the error insufficient permissions
. I thought I can do this workaround with signInAnonymously
but apparently this is not working.
These are my Cloud-Firestore-Rules
:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read;
allow write: if request.auth != null;
}
}
}
Can anyone help me out here? I hope everything is clear, let me know if you need more information.
Upvotes: 0
Views: 661
Reputation: 598837
There are two ways to implement this:
In the client-side code: first delete the user's document from the database, and only then delete their account. So the order is exactly the opposite of how you do it now, because there's no secure way to delete the account from the client once the account is deleted. I.e. if you make your current approach work, anyone can delete anyone else's user document, which is a big security risk.
Create a Cloud Function that deletes the user's document when their account is deleted.
Upvotes: 1