{"id":14973123,"url":"https://github.com/cgossain/firebaseidentity","last_synced_at":"2026-02-14T20:36:35.756Z","repository":{"id":56335589,"uuid":"199365140","full_name":"cgossain/FirebaseIdentity","owner":"cgossain","description":"A lightweight library that streamlines interaction with the Firebase/Auth library on iOS, written in Swift.","archived":false,"fork":false,"pushed_at":"2024-12-10T18:59:27.000Z","size":57996,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-26T16:49:45.197Z","etag":null,"topics":["firebase","firebase-auth","firebase-authentication","identity","identity-management","identity-provider","ui"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cgossain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-29T02:38:46.000Z","updated_at":"2024-12-10T18:59:31.000Z","dependencies_parsed_at":"2024-02-20T23:28:50.008Z","dependency_job_id":"e341759c-67b6-4104-9fc8-4bbefa7809d0","html_url":"https://github.com/cgossain/FirebaseIdentity","commit_stats":{"total_commits":83,"total_committers":1,"mean_commits":83.0,"dds":0.0,"last_synced_commit":"b26b18f33e40bf7c8b9447b1adc50c412dbe3cf1"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/cgossain/FirebaseIdentity","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgossain%2FFirebaseIdentity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgossain%2FFirebaseIdentity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgossain%2FFirebaseIdentity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgossain%2FFirebaseIdentity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cgossain","download_url":"https://codeload.github.com/cgossain/FirebaseIdentity/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgossain%2FFirebaseIdentity/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272612176,"owners_count":24964388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["firebase","firebase-auth","firebase-authentication","identity","identity-management","identity-provider","ui"],"created_at":"2024-09-24T13:48:09.662Z","updated_at":"2025-10-08T18:56:48.730Z","avatar_url":"https://github.com/cgossain.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FirebaseIdentity\n\nThe primary motivation of this library is to make building custom UI around the Firebase Authentication\nservice easier on iOS for those of us that do not want to use the FirebaseUI library. \n\nIt does this by implementing standard authentication workflows and error handling (i.e. account linking, profile \nupdates, set/update password, reauthentication, enable/disable thrid-party identity providers, account deletion,\nauto-retry, etc.). This is done by abstracting away a lot of the error handling logic into a singleton\nstate machine (called AuthManager) capable of handling most Firebase authentication use cases.\n\n[![CI Status](https://img.shields.io/travis/cgossain/FirebaseIdentity.svg?style=flat)](https://travis-ci.org/cgossain/FirebaseIdentity)\n[![Version](https://img.shields.io/cocoapods/v/FirebaseIdentity.svg?style=flat)](https://cocoapods.org/pods/FirebaseIdentity)\n[![License](https://img.shields.io/cocoapods/l/FirebaseIdentity.svg?style=flat)](https://cocoapods.org/pods/FirebaseIdentity)\n[![Platform](https://img.shields.io/cocoapods/p/FirebaseIdentity.svg?style=flat)](https://cocoapods.org/pods/FirebaseIdentity)\n\n## Usage\n\n### AuthManager\n\nThe main class you'll work with is `AuthManager`, and is intended to be used as a singleton.\n\nThe setup should be done as early as possible in the app lifecycle after initializing the Firebase library.\n\n\u003cpre\u003e\nfunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -\u003e Bool {\n    ...\n    \n    // firebase\n    \u003cb\u003eFirebaseApp.configure()\u003c/b\u003e\n\n    // facebook\n    ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)\n    \n    // configure other auth providers as needed\n    ...\n\n    // auth manager\n    \u003cb\u003eAuthManager.configure()\u003c/b\u003e\n\n    // observer auth state\n    // the auth manager state changes as the Firebase authentication state changes; by listening to this state change \n    // you can appropriately update your UI\n    authenticationStateObserver =\n        NotificationCenter.default.addObserver(forName: AuthManager.authenticationStateChangedNotification, object: nil, queue: .main, using: { (note) in\n            guard let manager = note.object as? AuthManager else {\n                return\n            }\n\n            switch manager.authenticationState {\n            case .authenticated:\n                AppController.login()\n            case .notDetermined, .notAuthenticated:\n                AppController.logout()\n            }\n        })\n        \n    ...\n    \n    return true\n}\n\u003c/pre\u003e\n\n### IdentityProvider\n\nSign-in providers are modelled by the `IdentityProvider` class.\n\nCurrently the only providers that have been implemented are `EmailIdentityProvider` and `FacebookIdentityProvider`, but you could easily subclass `IdentityProvider` to implement any other identity provider you. Feel free to submit a pull request if you implement other ones :)\n\nTo sign up a new user using email authentication:\n\n```\nlet provider = EmailIdentityProvider(email: user.email, password: user.password)\nAuthManager.shared.signUp(with: provider) { (result) in\n    switch result {\n    case .success(let value):\n        print(value)\n\n    case .failure(let error):\n        self.showAuthenticationErrorAlert(for: error)\n    }\n}\n```\n\nTo sign up/in a user with Facebook authentication:\n\n```\nlet requestedPermissions: [String] = [\"email\"]\nfbLoginManager.logIn(permissions: requestedPermissions, from: self) { (result, error) in\n    guard let result = result, !result.isCancelled else {\n        if let error = error {\n            print(error.localizedDescription)\n            self.showAlert(for: error)\n        }\n        return\n    }\n\n    let token = AccessToken.current!.tokenString\n    let provider = FaceboookIdentityProvider(accessToken: token)\n    AuthManager.shared.signUp(with: provider) { (result) in\n        switch result {\n        case .success(let value):\n            print(value)\n\n        case .failure(let error):\n            self.showAuthenticationErrorAlert(for: error)\n        }\n    }\n}\n```\n \nThere are many other examples included in the demo project that you should check out.\n\n### AuthManagerReauthenticating\n\nThere are some user profile changes in Firebase that require a recent login. In particular, Firebase will trigger the `FIRAuthErrorCodeRequiresRecentLogin = 17014,` error in these situations.\n\nThis library handles this error via the `AuthManagerReauthenticating` protocol. \n\nGiven that a user may have multiple identity providers linked to their account, this protocol is used to offload the decision of which one to use for reauthentication. One way to implement this could be by simply presenting UI to the user asking them to reauthenticate using one of the given identity providers (further offloading the decision to the user). Alternatively, you could implement by simply asking for reauthentication from the highest priority identify provider.\n\nAs an added bonus, this library also locally caches the last user sign in date and will optimistically request reauthentication if more that 5 minutes (the currently documented Firebase recent sign in threshhold) have elapsed since the last sign in. The benefit of caching this locally is that we can avoid an additional network request that we know will generate the `17014` error anyways (slightly speeds things up from the users perspective).\n\nKeep in mind that reauthentication only applies when a user is already signed in, so a good place to implement this protocol would be on a view controller that provides UI related to account management. For example,\n\n```\nextension AccountViewController: AuthManagerReauthenticating {\n    func authManager(_ manager: AuthManager, reauthenticateUsing providers: [IdentityProviderUserInfo], challenge: ProfileChangeReauthenticationChallenge) {\n        // ask for reauthentication from the highest priority auth provider\n        guard let provider = providers.first else {\n            return\n        }\n\n        switch provider.providerID {\n        case .email:\n            // an email provider will always have an email associated with it, therefore it should be safe to force unwrap this value here;\n            // what if there is some kind of error that causes the email to be non-existant in this scenario? Force the user to log-out, then back in?\n            // it seems like it would be impossible for the email to not exist on an email auth provider\n            let email = provider.email!\n\n            // present UI for user to provider their current password\n            let alert = UIAlertController(title: \"Confirm Password\", message: \"Your current password is required to change your email address.\\n\\nCurrent Email: \\(email)\\nTarget Email:\\(challenge.context.profileChangeType.attemptedValue)\", preferredStyle: .actionSheet)\n            for password in Set(AuthManager.debugEmailProviderUsers.map({ $0.password })) {\n                alert.addAction(UIAlertAction(title: password, style: .default, handler: { (action) in\n                    let provider = EmailIdentityProvider(email: email, password: password)\n                    manager.reauthenticate(with: provider, for: challenge) { (error) in\n                        guard let error = error else {\n                            return\n                        }\n                        self.showAuthenticationErrorAlert(for: error)\n                    }\n                }))\n            }\n\n            alert.addAction(UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil))\n            self.present(alert, animated: true, completion: nil)\n        case .facebook:\n            fetchFacebookAccessTokenForReauthentication { (token) in\n                guard let token = token else {\n                    return\n                }\n                let provider = FaceboookIdentityProvider(accessToken: token)\n                manager.reauthenticate(with: provider, for: challenge) { (error) in\n                    guard let error = error else {\n                        return\n                    }\n                    self.showAuthenticationErrorAlert(for: error)\n                }\n            }\n        default:\n            print(\"undefined provider\")\n        }\n    }\n}\n```\n\nThis is implemented in the `SignedInViewController` in the included demo project.\n\n### Account Deletion\n\nYou may want to provide your users the ability to delete their own account.\n\nThis library facilitates this by providing the `DeleteAccountOperation`.\n\nTo delete a users' account:\n\n```\n...\n\n// optionally provide database refs to delete (i.e. user scoped refs); these will be deleted before the account is deleted\nlet userRefs: [DatabaseReference]? = [userRef1, userRef2, ...]\n\n// create a new op instance\nlet deleteAccountOp = DeleteAccountOperation(refs: userRefs)\ndeleteAccountOp.deleteAccountCompletionBlock = { [unowned self] (result) in\n    DispatchQueue.main.async {\n        switch result {\n        case .success(let user):\n            // post account deletion (i.e. show login screen, track event, etc.)\n\n        case .failure(let error):\n            switch error {\n            case .cancelledByUser:\n                break\n            case .other(let msg):\n                // show alert\n            }\n        }\n    }\n}\n\n// pass the op to the AuthManager\nAuthManager.shared.deleteAccount(with: deleteAccountOp)\n\n...\n\n```\n\n\n## Example\n\nThe included demo project showcases the full functionality of this library.\n\n### Prerequisites\n\nTo run the demo project, clone the repo, and run `pod install` from the Example directory first.\n\nYou'll also need a Firebase account. From your Firebase account, follow the instructions to create a demo project and add an iOS app to it. You'll then need to download its corresponding `GoogleService-Info.plist` file and add it the demo project in Xcode. The Firebase framework automatically detects this file when the app launches and will configure the environment accordingly.\n\n## Requirements\n\n- iOS 12.4+\n- Swift 5+\n- A Firebase account\n\n## Installation\n\nFirebaseIdentity is available through [CocoaPods](https://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod 'FirebaseIdentity'\n```\n\n## Author\n\ncgossain, cgossain@gmail.com\n\n## License\n\nFirebaseIdentity is available under the MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcgossain%2Ffirebaseidentity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcgossain%2Ffirebaseidentity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcgossain%2Ffirebaseidentity/lists"}