Last active
July 10, 2022 06:30
-
-
Save longvudai/cc0d64abacc83050e12e92a2e591fe52 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Firebase | |
import FirebaseAuth | |
extension FirebaseApp { | |
private static var didConfigForAppExtension = false | |
static func configureFirebaseForAppExtension( | |
extensionPlistName: String, | |
accessGroup: String, | |
force: Bool = false | |
) { | |
func configure() { | |
// Shared firebase auth state for extension | |
copyContainerFirebaseData() | |
configureFirebase(plistName: extensionPlistName, accessGroup: accessGroup) | |
} | |
if !force { | |
guard !didConfigForAppExtension else { | |
return | |
} | |
configure() | |
didConfigForAppExtension = true | |
} else { | |
configure() | |
} | |
} | |
static func configureFirebase(plistName: String, accessGroup: String) { | |
func configure(plistName: String) { | |
guard | |
let configURL = Bundle.main.url(forResource: plistName, withExtension: "plist"), | |
let options = FirebaseOptions(contentsOfFile: configURL.path) | |
else { | |
return | |
} | |
FirebaseApp.configure(options: options) | |
} | |
configure(plistName: plistName) | |
// In each app, set the access group to the keychain access group or app group | |
Auth.switchToUsingAppGroup(accessGroup) | |
Auth.migrateFirebaseAuthToAccessGroupIfNeeded(accessGroup) | |
} | |
private static func copyContainerFirebaseData() { | |
do { | |
let fileManager = FileManager.default | |
guard let localFirebaseURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("firebase") else { | |
assertionFailure("Unable to get shared container") | |
return | |
} | |
try PersistenceSyncManager.shared.copyContentsFromSharedTarget(to: localFirebaseURL) | |
} catch { | |
assertionFailure(error.localizedDescription) | |
} | |
} | |
} | |
private extension FirebaseAuth.Auth { | |
static func switchToUsingAppGroup(_ accessGroup: String) { | |
do { | |
try Auth.auth().useUserAccessGroup(accessGroup) | |
} catch let error as NSError { | |
print("Error changing user access group: %@", error) | |
} | |
} | |
// it basically checks if Auth is already using the correct userAccessGroup and | |
// if so, nothing needs to be done. | |
// If not, the existing user is temporary saved, | |
// then Firebase Auth is configured to use the Access Group and then the user is moved to it. | |
static func migrateFirebaseAuthToAccessGroupIfNeeded(_ accessGroup: String) { | |
let auth = Auth.auth() | |
// get current user (so we can migrate later) | |
guard let user = auth.currentUser else { | |
print("currentUser is nil") | |
return | |
} | |
if auth.userAccessGroup == accessGroup { | |
print("Firebase Auth is already using the correct acces group \(accessGroup)") | |
return | |
} | |
print("Firebase Auth is not yet using correct access group \(accessGroup). 🔄 Migrating...") | |
// for extension (widget) we want to share our auth status | |
do { | |
// switch to using app group | |
try auth.useUserAccessGroup(accessGroup) | |
// migrate current user | |
auth.updateCurrentUser(user) { error in | |
if let error = error { | |
print("Auth.auth().updateCurrentUser \(error.localizedDescription)") | |
} else { | |
print("Firebase Auth user migrated") | |
} | |
} | |
} catch let error as NSError { | |
print("❌ Error changing user access group \(accessGroup): \(error.localizedDescription)") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment