当前位置: 首页 > 知识库问答 >
问题:

Firebase在iOS上删除帐户以及数据库和存储

咸承教
2023-03-14

我试图实现一个功能来删除当前用户的帐户上iOS。帐户删除工作正常,但问题是删除帐户时,我无法从数据库和存储中删除帐户的数据。

“currentUser.delete”删除该帐户,但我认为没有身份验证可以从数据库和存储中删除其数据。日志中将显示“权限被拒绝”消息。运行此功能后,我看到Firebase控制台验证页面中的帐户已消失,但来自数据库和存储的数据仍然存在。

这是删除帐户的正确方法吗?

在删除帐户之前,我试图从数据库和存储中删除数据。但是,如果会话超过5分钟,Firebase会要求重新验证。在再次执行帐户删除之前,重新登录会向用户显示空数据,因此这会产生误导,并且非常令人困惑。

请告诉我删除帐户时如何删除数据。

private func deleteAccount() {
  guard let currentUser = Auth.auth().currentUser else {
    return print("user not logged in")
  }

  currentUser.delete { error in
    if error == nil {
      // 1. Delete currentUser's data from Database. Permission denied
      // 2. Delete currentUser's data from Storage. Permission denied
      // present login screen (welcome page)
      self.presentLoginScreen()
    } else {
      guard let errorCode = AuthErrorCode(rawValue: error!._code) else { return }

      if errorCode == AuthErrorCode.requiresRecentLogin {
        self.showMessage("Please re-authenticate to delete your account.", type: .error)

        do {
          try Auth.auth().signOut()
          self.presentLoginScreen()
        } catch {
          print("There was a problem logging out")
        }
      }
    }
  }
}

共有2个答案

牟嘉
2023-03-14

要解决您提到的问题(在删除实际用户之前删除数据,并可能获得authrorcode.requiresRecentLogin错误),您可以使用DispatchGroup并检查LastSignendate,如下所示(只需调用deleteUserProcess()):

let deleteDataGroup = DispatchGroup()

func deleteUserProcess() {
    guard let currentUser = Auth.auth().currentUser else { return }
    deleteUserData(user: currentUser)
    // Call deleteUser only when all data has been deleted
    deleteDataGroup.notify(queue: .main) {
        self.deleteUser(user: currentUser)
    }
}
/// Remove data from Database & Storage
func deleteUserData(user currentUser: User) {
    // Check if `currentUser.delete()` won't require re-authentication
    if let lastSignInDate = currentUser.metadata.lastSignInDate,
        lastSignInDate.minutes(from: Date()) >= -5 {
        deleteDataGroup.enter()
        Database.database().reference().child(userId).removeValue { error, _ in
            if let error = error { print(error) }
            self.deleteDataGroup.leave()
        }
        // Delete folders from Storage isn't possible,
        // so list and run over all files to delete each one independently
        deleteDataGroup.enter()
        Storage.storage().reference().child(userId).listAll { list, error in
            if let error = error { print(error) }
            list.items.forEach({ file in
                self.deleteDataGroup.enter()
                file.delete { error in
                    if let error = error { print(error) }
                    self.deleteDataGroup.leave()
                }
            })
            deleteDataGroup.leave()
        }
    }
}

/// Delete user
func deleteUser(user currentUser: 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
        // TODO: Redirect to the login UI
    }
}

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
            }
            // TODO: Dismiss UI
            // Call `deleteUserProcess()` again, this time it will delete the user
            deleteUserProcess()
        }
    }
}

小步舞曲功能可以添加日期的扩展中(感谢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
    }
}
罗昱
2023-03-14

您可以首先通过UID删除特定用户及其值,然后删除用户,并在删除后将其带到根视图控制器或登录屏幕。

// removing user data from firebase and its specific user id 
         let user = Auth.auth().currentUser
        user?.delete { error in
          if let error = error {
            // An error happened.
            print(error.localizedDescription)
          } else {
            Database.database().reference().child("users").child(user?.uid ?? "").removeValue()
            self.navigationController?.popToRootViewController(animated: true)
            // Account deleted and logout user
//            do {
//                try Auth.auth().signOut()
                // take you to root
//                self.navigationController?.popToRootViewController(animated: true)


        }
 类似资料:
  • 我想从Firebase中删除我的当前用户。经过身份验证的用户被删除,但是我无法删除数据库中该用户的数据。我做错了什么? 这是我的删除用户方法。。。。 Firebase规则: 数据库: 错误: 2017-01-21 21:33:10.321704应用程序[11582:4102711][FirebaseDatabase]设置值:或删除值:at/users/4erkjkl543jfe46失败:权限被拒绝

  • 我仍在开发我的登录应用程序。此时,用户可以注册、登录和更新配置文件信息。数据存储在firebase实时数据库中,该装置也通过firebase工作。我想添加一个“删除配置文件”按钮,以便从firebase中删除用户信息。我弄清楚了如何从自动认证过程中删除用户。现在我尝试对Uid调用remove()函数,因此现在数据在实时数据库中被删除,但仍在Firebase身份验证中,如果删除userdata,应用

  • 首先,我将引用另外两个对这个问题有部分答案的问题。 删除VM后从Azure中删除磁盘 如何删除Microsoft Azure存储中的租用blob 使用Azure Explorer,我可以删除blob和容器,但当我尝试删除存储帐户时,我出现了以下错误: 删除存储帐户“bitnamiWestusflwdmy”失败。无法删除存储帐户“bitnamiWestusflwdmy”:“存储帐户bitnamiWe

  • 我在我的react本地应用程序中使用Firebase实时数据库。大多数事情都是通过REST API云函数来完成的。app中很少东西直接使用实时数据库。最近,我发现我数据库中的所有数据都被莫名其妙地删除了。甚至数据库中不再使用且未在我的应用程序/云功能的源代码中引用的部分也消失了。 问题发生在两个项目及其数据库(生产/测试)中。我必须使用备份来恢复它们,但即使没有人使用应用程序(例如,在测试环境中)

  • 我正在尝试将用户保存到我的Firebase数据库。我正在使用创建帐户/登录。创建帐户后,我想将用户存储到我的Firebase数据库中。我目前可以登录用户,他们的电子邮件显示在Firebase的Auth选项卡中(见屏幕截图),但我的似乎没有任何影响(另见屏幕截图)。 我是否将updatechildvalue放在了正确的位置?它当前位于带有凭据的登录中。我还必须执行FBSDKGraphRequest以

  • 我以为上面的办法行得通,但它失败了。我把它放在渲染行部分。它出现了reference.remove失败。第一个参数必须是有效的函数。就像在这些房间里,它有信息,我认为这是我出错的地方,但我不知道如何去做它。谢谢。