Firebase 删除帐户以及 iOS 上的数据库和存储
Posted
技术标签:
【中文标题】Firebase 删除帐户以及 iOS 上的数据库和存储【英文标题】:Firebase delete account along with Database and Storage on iOS 【发布时间】:2018-11-13 09:18:47 【问题描述】:我正在尝试实现在 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")
【问题讨论】:
在删除帐户之前删除数据是从客户端实现此目的的唯一方法。但是,当您说“我在删除帐户之前尝试从数据库和存储中删除数据。但是,如果会话超过 5 分钟,Firebase 会要求重新进行身份验证”,但我不明白您的意思。我不明白这里有什么问题。如果用户帐户被删除,那几乎就结束了,对吧? 嗨,Doug,如果用户的会话超过 5 分钟,他会返回欢迎页面。但是随后该用户将看到空数据,并且必须转到设置页面再次执行帐户删除。我认为这很令人困惑。 1. 用户进入设置页面删除账户。 2. 他被要求重新认证并自动返回欢迎页面。 3.他再次登录,但数据全部消失,帐户仍然存在。 4.他必须去设置页面再次删除帐户。这不是很奇怪吗? 您正在删除该帐户。在那种情况下,我希望一切都会重置。会话年龄与任何事情无关。这里有什么事情你没有分享吗? 不需要用UID识别用户相关数据吗?因此,您只需创建一个函数来删除包含/与该特定 UID 相关的内容。 我相信会话年龄确实很重要。如果它超过 5 分钟,我会收到一个错误,在 else 语句中处理。因此,如果会话旧,此错误会阻止删除帐户。 【参考方案1】:斯威夫特 5 | Firebase 8.11.0
要解决您提到的问题(在删除实际用户之前删除数据并可能得到AuthErrorCode.requiresRecentLogin
错误),您可以使用DispatchGroup
并检查lastSignInDate
,就像这样(只需调用@ 987654325@):
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://***.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()
小步舞曲功能可以添加到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
【讨论】:
【参考方案2】:您可以先删除您的特定用户,并通过其 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 删除帐户以及 iOS 上的数据库和存储的主要内容,如果未能解决你的问题,请参考以下文章
当我在firebase上删除他的帐户时如何从应用程序中注销用户?