Skip to content

Commit 3efb024

Browse files
authored
[Auth] Get 'currentUser' on Auth worker queue (#14141)
1 parent 56d4c18 commit 3efb024

File tree

2 files changed

+31
-20
lines changed

2 files changed

+31
-20
lines changed

FirebaseAuth/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Unreleased
2+
- [fixed] Restore Firebase 10 behavior by synchronizing access to the
3+
`Auth.currentUser` API. This resolves some Firebase 11 issues where the
4+
current user is unexpectedly `nil` at startup.
5+
16
# 11.5.0
27
- [fixed] Restore pre-Firebase 11 decoding behavior to prevent users getting
38
logged out when upgrading from Firebase 8.10.0 or earlier to Firebase 11.

FirebaseAuth/Sources/Swift/Auth/Auth.swift

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ extension Auth: AuthInterop {
116116
}
117117
}
118118
// Call back with 'nil' if there is no current user.
119-
guard let strongSelf = self, let currentUser = strongSelf.currentUser else {
119+
guard let strongSelf = self, let currentUser = strongSelf._currentUser else {
120120
DispatchQueue.main.async {
121121
callback(nil, nil)
122122
}
@@ -136,7 +136,7 @@ extension Auth: AuthInterop {
136136
///
137137
/// This method is not for public use. It is for Firebase clients of AuthInterop.
138138
open func getUserID() -> String? {
139-
return currentUser?.uid
139+
return _currentUser?.uid
140140
}
141141
}
142142

@@ -170,7 +170,13 @@ extension Auth: AuthInterop {
170170
@objc public internal(set) weak var app: FirebaseApp?
171171

172172
/// Synchronously gets the cached current user, or null if there is none.
173-
@objc public internal(set) var currentUser: User?
173+
@objc public var currentUser: User? {
174+
kAuthGlobalWorkQueue.sync {
175+
_currentUser
176+
}
177+
}
178+
179+
private var _currentUser: User?
174180

175181
/// The current user language code.
176182
///
@@ -702,7 +708,7 @@ extension Auth: AuthInterop {
702708
@objc open func signInAnonymously(completion: ((AuthDataResult?, Error?) -> Void)? = nil) {
703709
kAuthGlobalWorkQueue.async {
704710
let decoratedCallback = self.signInFlowAuthDataResultCallback(byDecorating: completion)
705-
if let currentUser = self.currentUser, currentUser.isAnonymous {
711+
if let currentUser = self._currentUser, currentUser.isAnonymous {
706712
let result = AuthDataResult(withUser: currentUser, additionalUserInfo: nil)
707713
decoratedCallback(result, nil)
708714
return
@@ -1264,7 +1270,7 @@ extension Auth: AuthInterop {
12641270
/// dictionary will contain more information about the error encountered.
12651271
@objc(signOut:) open func signOut() throws {
12661272
try kAuthGlobalWorkQueue.sync {
1267-
guard self.currentUser != nil else {
1273+
guard self._currentUser != nil else {
12681274
return
12691275
}
12701276
return try self.updateCurrentUser(nil, byForce: false, savingToDisk: true)
@@ -1385,14 +1391,14 @@ extension Auth: AuthInterop {
13851391
queue: OperationQueue.main
13861392
) { notification in
13871393
if let auth = notification.object as? Auth {
1388-
listener(auth, auth.currentUser)
1394+
listener(auth, auth._currentUser)
13891395
}
13901396
}
13911397
objc_sync_enter(Auth.self)
13921398
listenerHandles.add(listener)
13931399
objc_sync_exit(Auth.self)
13941400
DispatchQueue.main.async {
1395-
listener(self, self.currentUser)
1401+
listener(self, self._currentUser)
13961402
}
13971403
return handle
13981404
}
@@ -1434,7 +1440,7 @@ extension Auth: AuthInterop {
14341440
/// complete, or fails. Invoked asynchronously on the main thread in the future.
14351441
@objc open func revokeToken(withAuthorizationCode authorizationCode: String,
14361442
completion: ((Error?) -> Void)? = nil) {
1437-
currentUser?.internalGetToken(backend: backend) { idToken, error in
1443+
_currentUser?.internalGetToken(backend: backend) { idToken, error in
14381444
if let error {
14391445
Auth.wrapMainAsync(completion, error)
14401446
return
@@ -1790,7 +1796,7 @@ extension Auth: AuthInterop {
17901796
}
17911797

17921798
func updateKeychain(withUser user: User?) -> Error? {
1793-
if user != currentUser {
1799+
if user != _currentUser {
17941800
// No-op if the user is no longer signed in. This is not considered an error as we don't check
17951801
// whether the user is still current on other callbacks of user operations either.
17961802
return nil
@@ -1836,7 +1842,7 @@ extension Auth: AuthInterop {
18361842
}
18371843

18381844
func signOutByForce(withUserID userID: String) throws {
1839-
guard currentUser?.uid == userID else {
1845+
guard _currentUser?.uid == userID else {
18401846
return
18411847
}
18421848
try updateCurrentUser(nil, byForce: true, savingToDisk: true)
@@ -1846,7 +1852,7 @@ extension Auth: AuthInterop {
18461852

18471853
/// Posts the auth state change notification if current user's token has been changed.
18481854
private func possiblyPostAuthStateChangeNotification() {
1849-
let token = currentUser?.rawAccessToken()
1855+
let token = _currentUser?.rawAccessToken()
18501856
if lastNotifiedUserToken == token ||
18511857
(token != nil && lastNotifiedUserToken == token) {
18521858
return
@@ -1863,7 +1869,7 @@ extension Auth: AuthInterop {
18631869
if let token, token.count > 0 {
18641870
internalNotificationParameters[FIRAuthStateDidChangeInternalNotificationTokenKey] = token
18651871
}
1866-
internalNotificationParameters[FIRAuthStateDidChangeInternalNotificationUIDKey] = currentUser?
1872+
internalNotificationParameters[FIRAuthStateDidChangeInternalNotificationUIDKey] = _currentUser?
18671873
.uid
18681874
let notifications = NotificationCenter.default
18691875
DispatchQueue.main.async {
@@ -1880,7 +1886,7 @@ extension Auth: AuthInterop {
18801886
/// If the token expires in less than 5 minutes, schedule the token refresh immediately.
18811887
private func scheduleAutoTokenRefresh() {
18821888
let tokenExpirationInterval =
1883-
(currentUser?.accessTokenExpirationDate()?.timeIntervalSinceNow ?? 0) - 5 * 60
1889+
(_currentUser?.accessTokenExpirationDate()?.timeIntervalSinceNow ?? 0) - 5 * 60
18841890
scheduleAutoTokenRefresh(withDelay: max(tokenExpirationInterval, 0), retry: false)
18851891
}
18861892

@@ -1889,7 +1895,7 @@ extension Auth: AuthInterop {
18891895
/// to be executed.
18901896
/// - Parameter retry: Flag to determine whether the invocation is a retry attempt or not.
18911897
private func scheduleAutoTokenRefresh(withDelay delay: TimeInterval, retry: Bool) {
1892-
guard let accessToken = currentUser?.rawAccessToken() else {
1898+
guard let accessToken = _currentUser?.rawAccessToken() else {
18931899
return
18941900
}
18951901
let intDelay = Int(ceil(delay))
@@ -1908,18 +1914,18 @@ extension Auth: AuthInterop {
19081914
guard let strongSelf = weakSelf else {
19091915
return
19101916
}
1911-
guard strongSelf.currentUser?.rawAccessToken() == accessToken else {
1917+
guard strongSelf._currentUser?.rawAccessToken() == accessToken else {
19121918
// Another auto refresh must have been scheduled, so keep _autoRefreshScheduled unchanged.
19131919
return
19141920
}
19151921
strongSelf.autoRefreshScheduled = false
19161922
if strongSelf.isAppInBackground {
19171923
return
19181924
}
1919-
let uid = strongSelf.currentUser?.uid
1920-
strongSelf.currentUser?
1925+
let uid = strongSelf._currentUser?.uid
1926+
strongSelf._currentUser?
19211927
.internalGetToken(forceRefresh: true, backend: strongSelf.backend) { token, error in
1922-
if strongSelf.currentUser?.uid != uid {
1928+
if strongSelf._currentUser?.uid != uid {
19231929
return
19241930
}
19251931
if error != nil {
@@ -1943,7 +1949,7 @@ extension Auth: AuthInterop {
19431949
/// - Parameter saveToDisk: Indicates the method should persist the user data to disk.
19441950
func updateCurrentUser(_ user: User?, byForce force: Bool,
19451951
savingToDisk saveToDisk: Bool) throws {
1946-
if user == currentUser {
1952+
if user == _currentUser {
19471953
possiblyPostAuthStateChangeNotification()
19481954
}
19491955
if let user {
@@ -1960,7 +1966,7 @@ extension Auth: AuthInterop {
19601966
}
19611967
}
19621968
if throwError == nil || force {
1963-
currentUser = user
1969+
_currentUser = user
19641970
possiblyPostAuthStateChangeNotification()
19651971
}
19661972
if let throwError {

0 commit comments

Comments
 (0)