Skip to content

Commit 2495c20

Browse files
authored
[Auth] Schedule keychain access after prewarming (#14142)
1 parent 3efb024 commit 2495c20

File tree

2 files changed

+38
-33
lines changed

2 files changed

+38
-33
lines changed

FirebaseAuth/Sources/Swift/Auth/Auth.swift

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,7 +1624,6 @@ extension Auth: AuthInterop {
16241624
keychainStorageProvider: AuthKeychainStorage = AuthKeychainStorageReal(),
16251625
backend: AuthBackend = .init(rpcIssuer: AuthBackendRPCIssuer()),
16261626
authDispatcher: AuthDispatcher = .init()) {
1627-
Auth.setKeychainServiceNameForApp(app)
16281627
self.app = app
16291628
mainBundleUrlTypes = Bundle.main
16301629
.object(forInfoDictionaryKey: "CFBundleURLTypes") as? [[String: Any]]
@@ -1650,27 +1649,28 @@ extension Auth: AuthInterop {
16501649
appCheck: appCheck)
16511650
self.backend = backend
16521651
self.authDispatcher = authDispatcher
1652+
1653+
let keychainServiceName = Auth.keychainServiceName(for: app)
1654+
keychainServices = AuthKeychainServices(service: keychainServiceName,
1655+
storage: keychainStorageProvider)
1656+
storedUserManager = AuthStoredUserManager(
1657+
serviceName: keychainServiceName,
1658+
keychainServices: keychainServices
1659+
)
1660+
16531661
super.init()
16541662
requestConfiguration.auth = self
16551663

1656-
protectedDataInitialization(keychainStorageProvider)
1664+
protectedDataInitialization()
16571665
}
16581666

1659-
private func protectedDataInitialization(_ keychainStorageProvider: AuthKeychainStorage) {
1667+
private func protectedDataInitialization() {
16601668
// Continue with the rest of initialization in the work thread.
16611669
kAuthGlobalWorkQueue.async { [weak self] in
16621670
// Load current user from Keychain.
16631671
guard let self else {
16641672
return
16651673
}
1666-
if let keychainServiceName = Auth.keychainServiceName(forAppName: self.firebaseAppName) {
1667-
self.keychainServices = AuthKeychainServices(service: keychainServiceName,
1668-
storage: keychainStorageProvider)
1669-
self.storedUserManager = AuthStoredUserManager(
1670-
serviceName: keychainServiceName,
1671-
keychainServices: self.keychainServices
1672-
)
1673-
}
16741674

16751675
do {
16761676
if let storedUserAccessGroup = self.storedUserManager.getStoredUserAccessGroup() {
@@ -1729,21 +1729,21 @@ extension Auth: AuthInterop {
17291729

17301730
#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst)
17311731
private func addProtectedDataDidBecomeAvailableObserver() {
1732-
weak var weakSelf = self
17331732
protectedDataDidBecomeAvailableObserver =
17341733
NotificationCenter.default.addObserver(
17351734
forName: UIApplication.protectedDataDidBecomeAvailableNotification,
17361735
object: nil,
17371736
queue: nil
1738-
) { notification in
1739-
let strongSelf = weakSelf
1740-
if let observer = strongSelf?.protectedDataDidBecomeAvailableObserver {
1737+
) { [weak self] notification in
1738+
guard let self else { return }
1739+
if let observer = self.protectedDataDidBecomeAvailableObserver {
17411740
NotificationCenter.default.removeObserver(
17421741
observer,
17431742
name: UIApplication.protectedDataDidBecomeAvailableNotification,
17441743
object: nil
17451744
)
17461745
}
1746+
self.protectedDataInitialization()
17471747
}
17481748
}
17491749
#endif
@@ -1817,28 +1817,34 @@ extension Auth: AuthInterop {
18171817
/// @synchronized([FIRAuth class]) context.
18181818
fileprivate static var gKeychainServiceNameForAppName: [String: String] = [:]
18191819

1820-
/// Sets the keychain service name global data for the particular app.
1821-
/// - Parameter app: The Firebase app to set keychain service name for.
1822-
class func setKeychainServiceNameForApp(_ app: FirebaseApp) {
1823-
objc_sync_enter(Auth.self)
1824-
gKeychainServiceNameForAppName[app.name] = "firebase_auth_\(app.options.googleAppID)"
1825-
objc_sync_exit(Auth.self)
1826-
}
1827-
1828-
/// Gets the keychain service name global data for the particular app by name.
1829-
/// - Parameter appName: The name of the Firebase app to get keychain service name for.
1830-
class func keychainServiceName(forAppName appName: String) -> String? {
1820+
/// Gets the keychain service name global data for the particular app by
1821+
/// name, creating an entry for one if it does not exist.
1822+
/// - Parameter app: The Firebase app to get the keychain service name for.
1823+
/// - Returns: The keychain service name for the given app.
1824+
static func keychainServiceName(for app: FirebaseApp) -> String {
18311825
objc_sync_enter(Auth.self)
18321826
defer { objc_sync_exit(Auth.self) }
1833-
return gKeychainServiceNameForAppName[appName]
1827+
let appName = app.name
1828+
if let serviceName = gKeychainServiceNameForAppName[appName] {
1829+
return serviceName
1830+
} else {
1831+
let serviceName = "firebase_auth_\(app.options.googleAppID)"
1832+
gKeychainServiceNameForAppName[appName] = serviceName
1833+
return serviceName
1834+
}
18341835
}
18351836

18361837
/// Deletes the keychain service name global data for the particular app by name.
18371838
/// - Parameter appName: The name of the Firebase app to delete keychain service name for.
1838-
class func deleteKeychainServiceNameForAppName(_ appName: String) {
1839+
/// - Returns: The deleted keychain service name, if any.
1840+
static func deleteKeychainServiceNameForAppName(_ appName: String) -> String? {
18391841
objc_sync_enter(Auth.self)
1842+
defer { objc_sync_exit(Auth.self) }
1843+
guard let serviceName = gKeychainServiceNameForAppName[appName] else {
1844+
return nil
1845+
}
18401846
gKeychainServiceNameForAppName.removeValue(forKey: appName)
1841-
objc_sync_exit(Auth.self)
1847+
return serviceName
18421848
}
18431849

18441850
func signOutByForce(withUserID userID: String) throws {
@@ -2364,15 +2370,15 @@ extension Auth: AuthInterop {
23642370
// MARK: Private properties
23652371

23662372
/// The stored user manager.
2367-
private var storedUserManager: AuthStoredUserManager!
2373+
private let storedUserManager: AuthStoredUserManager
23682374

23692375
/// The Firebase app name.
23702376
private let firebaseAppName: String
23712377

23722378
private let authDispatcher: AuthDispatcher
23732379

23742380
/// The keychain service.
2375-
private var keychainServices: AuthKeychainServices!
2381+
private let keychainServices: AuthKeychainServices
23762382

23772383
/// The user access (ID) token used last time for posting auth state changed notification.
23782384
private var lastNotifiedUserToken: String?

FirebaseAuth/Sources/Swift/Auth/AuthComponent.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ class AuthComponent: NSObject, Library, ComponentLifecycleMaintainer {
7777
kAuthGlobalWorkQueue.async {
7878
// This doesn't stop any request already issued, see b/27704535
7979

80-
if let keychainServiceName = Auth.keychainServiceName(forAppName: app.name) {
81-
Auth.deleteKeychainServiceNameForAppName(app.name)
80+
if let keychainServiceName = Auth.deleteKeychainServiceNameForAppName(app.name) {
8281
let keychain = AuthKeychainServices(service: keychainServiceName)
8382
let userKey = "\(app.name)_firebase_user"
8483
try? keychain.removeData(forKey: userKey)

0 commit comments

Comments
 (0)