简体   繁体   English

iOS SWIFT:无法从 Firebase 数据库中删除用户

[英]iOS SWIFT: Unable to delete user from Firebase Database

I want to delete my current user from Firebase.我想从 Firebase 中删除我当前的用户。 The authenticated user gets deleted however, I am unable to delete the data for that user in the database.但是,经过身份验证的用户被删除,我无法删除数据库中该用户的数据。 What am i doing wrong?我究竟做错了什么?

This is my delete user method....这是我的删除用户方法....

FIRAuth.auth()?.signIn(withEmail: (emailTextField?.text)! , password: (passwordTextField?.text)!, completion: { (user, error) in
            if error == nil {
                print("User Authenticate!!!")
                let user = FIRAuth.auth()?.currentUser

                user?.delete(completion: { (error) in
                    if error != nil {
                        print("Error unable to delete user")

                    } else {

                        DataService.ds.deleteCurrentFirebaseDBUser()
                        KeychainWrapper.standard.removeObject(forKey: KEY_UID)
                        self.performSegue(withIdentifier: "goToLogin", sender: nil)
                    }
                })

            } else {
                //Password was wrong, unable to authenicate user. Data is not updated
                print("!!!ALERT!!! Unable to authenticate user")
                let alert = UIAlertController(title: "Incorrect Password", message: "Please re-enter your password", preferredStyle: UIAlertControllerStyle.alert)
                alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
                self.present(alert, animated: true, completion: nil)
            }

        })

Firebase Rules: Firebase 规则:

{
"rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

Database:数据库:

App
   -> users
           ->
             4erkjkl543jfe46
                            ->name
                            ->email

ERRORS:错误:

2017-01-21 21:33:10.321704 APP[11582:4102711] [FirebaseDatabase] setValue: or removeValue: at /users/4erkjkl543jfe46 failed: permission_denied 2017-01-21 21:33:10.321704 APP [11582:4102711] [FirebaseDatabase] setValue: 或 removeValue: at /users/4erkjkl543jfe46 失败:permission_denied

Optional(Error Domain=com.firebase Code=1 "Permission denied" UserInfo={NSLocalizedDescription=Permission denied})可选(错误域=com.firebase 代码=1“权限被拒绝”UserInfo={NSLocalizedDescription=权限被拒绝})

I'm having the same issue. 我有同样的问题。 You are not able to make use of your function deleteCurrentFirebaseDBUser() because the Firebase delete function (if successful) removes the user auth object. 您无法使用函数deleteCurrentFirebaseDBUser()因为Firebase删除功能(如果成功)会删除用户身份验证对象。

As a result user is not authenticated anymore at the time you want to delete user's data in database with deleteCurrentFirebaseDBUser() . 因此,当您要使用deleteCurrentFirebaseDBUser()删除数据库中的用户数据时,用户不再进行身份验证。

Currently I delete user's data in database before Firebase delete function which is not the ideal solution. 目前我在Firebase删除功能之前删除了数据库中的用户数据,这不是理想的解决方案。

We can delete user from both side authentication and database.But before that we need to reauthenticate user first then we get latest token to delete the user. 我们可以从双方身份验证和数据库中删除用户 。但在此之前我们需要首先重新验证用户,然后我们获取最新令牌以删除用户。

Here is the pretty code: 这是漂亮的代码:

  let user = Auth.auth().currentUser
            user?.reauthenticate(with:credential) { error in
                if let error = error {
                    // An error happened.
                    showAlertWithErrorMessage(message: error.localizedDescription)
                } else {
                    // User re-authenticated.
                    user?.delete { error in
                        if let error = error {
                            // An error happened.
                            showAlertWithErrorMessage(message: error.localizedDescription)
                        } else {
                            // Account deleted.
                            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
                        }
                    }

                }
            }

100% working in my project and well tested 100%在我的项目中工作并经过充分测试

for just to delete a child from Firebase use "removeValue()" 要从Firebase中删除子项,请使用“removeValue()”

 var db: DatabaseReference!
  override func viewDidLoad() {
        super.viewDidLoad()
        db = Database.database().reference()        
        deleteByID()
    }
 func deleteByID(){
        db.child("YOURID").removeValue()
    }

Swift 5 |斯威夫特 5 | Firebase 8.11.0火力基地 8.11.0

As @SvshX said, deleting the user data before deleting the actual user is the only available solution.正如@SvshX 所说,在删除实际用户之前删除用户数据是唯一可用的解决方案。

The problem with this method is that deleting the user might give an error like AuthErrorCode.requiresRecentLogin , then the data will be deleted but the user will not.这种方法的问题是删除用户可能会出现AuthErrorCode.requiresRecentLogin之类的错误,然后数据将被删除但用户不会。

This error is given when the last authentication of the user was more than 5 minuets ago (from Firebase Docs )当用户的最后一次身份验证超过 5 分钟前(来自Firebase Docs )时,会出现此错误

So, my final solution is:所以,我的最终解决方案是:

func deleteUser() {
    guard let currentUser = Auth.auth().currentUser else { return }

    // Check if `currentUser.delete()` won't require re-authentication
    if let lastSignInDate = currentUser.metadata.lastSignInDate,
        lastSignInDate.minutes(from: Date()) <= -5 {
        // Remove data from Database & Storage
        Database.database().reference().child(userId).removeValue()
        Storage.storage().reference().child(userId).delete()
        Storage.storage().reference().child(userId).delete()
    }

    // Delete user
    currentUser.delete { error in
        if let error = error {
            if AuthErrorCode(rawValue: error._code) == .requiresRecentLogin {
                reauthenticate()
            } else {
                // Another error occurred
            }
            return
        }

        // Logout properly
        try? Auth.auth().signOut()
        GIDSignIn.sharedInstance.signOut()
        LoginManager().logOut()

        // The user has been deleted successfully
    }
}

func reauthenticate() {
    // TODO: Display some UI to get credential from the user
    let credential = ... // Complete from https://stackoverflow.com/a/38253448/8157190
    Auth.auth().currentUser?.reauthenticate(with: credential) { _, error in
        if let error = error {
            print(error)
            return
        }

        // Reload user (to update metadata.lastSignInDate)
        Auth.auth().currentUser?.reload { error in
            if let error = error {
                print(error)
                return
            }
            // Call `deleteUser()` again, this time it will delete the user
            deleteUser()
        }
    }
}

The minuets function can be added in an extension to Date (thanks to Leo Dabus ): minuets 函数可以添加到Date的扩展中(感谢Leo Dabus ):

extension Date {
    /// Returns the amount of minutes from another date
    func minutes(from date: Date) -> Int {
        return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM