【问题标题】:firebase auth / swift - anonymous user not delete on applicationWillTerminate?firebase auth / swift - 匿名用户不会在 applicationWillTerminate 上删除?
【发布时间】:2018-04-03 14:32:28
【问题描述】:

所以在我的第一个加载屏幕上,我让用户匿名登录 - 所以他们有权访问 Firebase 数据库。代码如下:

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 每次运行时都会打印出来,这是应该发生的。但是在我的applicationWillTerminate 中,我尝试删除这个匿名用户,这样就不会有任何悬空的用户,但它不起作用。代码如下:

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")
                }
            })
        }
    }
}

打印出来:

will terminate
user exists
delete anonymous user

为什么它从不打印完成块?

【问题讨论】:

    标签: ios swift firebase firebase-authentication


    【解决方案1】:

    看起来这是个问题。我的第一个问题是你为什么要删除用户?

    查看this answer,您会看到,一旦匿名用户的身份验证令牌被删除/如果被 Firebase 遗忘,他们的帐户就会过期。这意味着将匿名用户从其帐户中注销会删除该用户。如果同一用户再次匿名登录,他们将获得一个新令牌。

    documentation 还声明:

    为了保护您的项目免遭滥用,Firebase 会限制您的应用在短时间内从同一 IP 地址获得的新电子邮件/密码和匿名注册的数量。您可以从 Firebase 控制台请求和安排对此配额的临时更改

    如果您尝试删除帐户以及与这些帐户关联的数据,我会查看此repo

    查看Authenticate with Firebase AnonymouslyDelete a User 文档没有提到删除匿名帐户。我认为这是因为注销它们与删除真实帐户是一回事。 这可能就是为什么调用Auth.auth().currentUser?.delete 似乎对匿名用户没有任何作用的原因。

    更新

    OP 确认您可以删除匿名用户。上面放在applicationDidEnterBackground 中的代码删除了该帐户。所以问题是为什么代码放在applicationWillTerminate里面时没有出现print语句。

    看着applicationWillTerminate

    您对该方法的实现大约有五秒钟的时间来执行任何任务并返回。如果该方法在时间到期之前没有返回,系统可能会完全杀死该进程。

    这可能是您看不到回调打印语句的原因。该应用程序在返回完成之前终止。我不能 100% 确定匿名登录的工作原理,但应该有其他方法来验证帐户是否已被删除。

    申请终止后是否需要重新登录?如果你这样做了,那么令牌就被删除了。

    另外,the app life cycle documentation states:

    应用必须随时准备终止,不应等待保存用户数据或执行其他关键任务。系统启动的终止是应用程序生命周期的正常部分。系统通常会终止应用程序,以便回收内存并为用户启动的其他应用程序腾出空间,但系统也可能会终止行为不端或未及时响应事件的应用程序。

    暂停的应用在终止时不会收到通知;系统杀死进程并回收相应的内存。如果应用程序当前正在后台运行且未挂起,则系统会在终止之前调用其应用程序委托的 applicationWillTerminate:。设备重启时系统不会调用该方法。

    除了系统终止您的应用之外,用户还可以使用多任务 UI 明确终止您的应用。用户发起的终止与终止暂停的应用程序具有相同的效果。应用程序的进程被杀死,并且没有通知发送到应用程序。

    由于暂停的应用没有收到applicationWillTerminate 通知,您可能需要重新考虑您的处理方式。

    【讨论】:

    • 嗯,好吧,我明白了。出于某种原因,如果我将删除帐户移动到applicationDidEnterBackground,它会删除匿名帐户,如果我将应用程序移动到后台而不终止,然后双击主页按钮并向上滑动终止。但是,当我双击并向上滑动以终止而不先移动到背景时,它不会删除。
    • 好吧,如果您在 applicationWillTerminate 中调用异步调用的回调,它就不会返回。也许这就是问题的一部分。但是您是说可以删除匿名帐户?只是想确保我更新我的答案是准确的。
    【解决方案2】:

    这很奇怪。乍一看,您似乎做的一切都是正确的。

    试试这个方法:

    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
                }
            }
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-22
      • 2017-01-31
      • 2016-10-20
      • 1970-01-01
      • 2016-12-06
      • 2019-12-06
      • 2020-01-07
      • 1970-01-01
      相关资源
      最近更新 更多