【问题标题】:Issue with addAuthStateDidChangeListener being called twiceaddAuthStateDidChangeListener 被调用两次的问题
【发布时间】:2016-10-03 14:42:33
【问题描述】:

我正在使用 Firebase,根据他们的文档,我正在检查用户的登录状态是否发生变化。问题存在于侦听器块中,当应用程序启动(用户登录)时,代码被调用两次。这不是什么大不了的事,但 Firebase 在连接中创建了两个值并删除了这两个值。我将如何解决这个问题?我需要在侦听器中而不是外部获取用户之后调用它,因为如果没有先完成获取用户数据,则无法保证用户将存在于该块之外。

FIRAuth.auth()?.addAuthStateDidChangeListener { auth, user in
        if let theUser = user {
            // User is signed in.

            // CODE IN HERE IS CALLED TWICE UPON APP LAUNCH (WHEN USERS LOGGED IN).... WHY?
            self.currentUser = theUser
            print("LOGGED IN!!!!")


            self.updateUsersStatus(user: self.currentUser)

        } else {
            // No user is signed in.
            self.performSegueWithIdentifier(SEGUE_LOG_IN, sender: self)
        }
    }

【问题讨论】:

  • 通常会发生这种情况,因为您在使用完 addAuthStateDidChangeListener 后没有删除它,而是继续启动它(例如,每次创建或出现视图控制器时,您都会启动 auth 事件,但您没有'当视图消失时不要删除它)
  • 检查此链接firebase.google.com/docs/reference/ios/firebaseauth/… 并确保删除 FIRAuthStateDidChangeListenerHandle 以避免重复调用
  • 你在哪个函数中调用这个方法?
  • 所有这些都在 viewDidLoad 中调用。据我了解,在单击 TabBarController 中的另一个视图后,侦听器停止收听,但是从您所说的不正确,我应该在 viewDidDisappear 中手动取消注册?
  • 想通了,我应该一直使用 if let user = FIRAuth.auth()?.currentUser { 因为用户已经登录而不是使用监听器。

标签: ios swift firebase firebase-realtime-database firebase-authentication


【解决方案1】:

+ 单击或选项 + 单击addAuthStateDidChangeListener 函数。您将看到以下内容:

Registers a block as an "auth state did change" listener. To be invoked when:
    - The block is registered as a listener,
    - The current user changes, or,
    - The current user's access token changes.

总而言之 - 块 get 立即被调用,然后很可能在验证 FIRApp 和/或 FIRAuth 对象不包含任何陈旧数据后再次被调用。因此,两次调用回调的行为应该是可以预料的,并且应该得到适当的管理。

【讨论】:

  • 我想这样做,但不确定如何在完成关闭中检查这些事件。我认为 auth 参数有一些状态属性,但我找不到类似的东西。我将如何针对每个事件执行这些检查?
  • 检查传递给块的用户参数不为零。如果它不为零,那么您有一个经过身份验证的用户。并在块的上下文之外检查经过身份验证的用户:FIRAuth.auth()?.currentUser != nil
【解决方案2】:

我遇到了 Jamie22 报告的相同问题。奇怪的事情 - 我有两个类似的应用程序设置,但只有一个应用程序在更改时调用了 auth 状态侦听器方法两次。

这个解决方法为我解决了这个问题:

var activeUser:FIRUser!

override func viewDidLoad() {
    super.viewDidLoad()

    FIRAuth.auth()?.addAuthStateDidChangeListener({ (auth:FIRAuth, user:FIRUser?) in
        if let user = user {
            if(self.activeUser != user){
                self.activeUser = user
                print("-> LOGGED IN AS \(user.email)")
            }
        } else {
            print("-> NOT LOGGED IN")
        }
    })
}

通过在身份验证状态更改时检查 appUser 是否已更改,您可以摆脱第二次调用,因为它将等于您在第一次调用中获得的用户。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 2012-05-05
    • 2017-01-19
    • 2014-02-04
    • 2016-12-13
    相关资源
    最近更新 更多