Joshua Martinez
Joshua Martinez

Reputation: 104

Maintain Firebase Authentication state after exiting app on iOS

I am using the following class to handle the authentication state and login for users:

class AuthenticationState: NSObject, ObservableObject {

     // MARK: Properties
    let db = Firestore.firestore()

    @Published var loggedInUser: FirebaseAuth.User?
    @Published var isAuthenticating = false
    @Published var error: NSError?

    static let shared = AuthenticationState()

    private let authState = Auth.auth()
    fileprivate var currentNonce: String?

    // MARK: Methods
    func login(with loginOption: LoginOption) {
        self.isAuthenticating = true
        self.error = nil

        switch loginOption {
            case .signInWithApple:
                handleSignInWithApple()

            case let .emailAndPassword(email, password):
                handleSignInWith(email: email, password: password)
        }
    }

    private func handleSignInWith(email: String, password: String) {
        authState.signIn(withEmail: email, password: password, completion: handleAuthResultCompletion)
    }

    func signup(email: String, password: String, passwordConfirmation: String) {
        guard password == passwordConfirmation else {
            self.error = NSError(domain: "", code: 9210, userInfo: [NSLocalizedDescriptionKey: "Password and confirmation does not match"])
            return
        }

        self.isAuthenticating = true
        self.error = nil

        authState.createUser(withEmail: email, password: password, completion: handleAuthResultCompletion)
    }

    private func handleAuthResultCompletion(auth: AuthDataResult?, error: Error?) {
        DispatchQueue.main.async {
        self.isAuthenticating = false
            if let user = auth?.user {
                self.loggedInUser = user
            } else if let error = error {
                self.error = error as NSError
            }
        }
    }

    func signout() {
        try? authState.signOut()
        self.loggedInUser = nil
    }
}

// Extension Below that handles sign in with apple, etc. 

This works great for handling a variety of sign in methods, however when the user exits the app, the logged in state no longer persists. What would be the best way to keep the user logged in after exiting the application?

Upvotes: 0

Views: 888

Answers (2)

Frank van Puffelen
Frank van Puffelen

Reputation: 599956

Firebase Authentication automatically persists the user's authentication state to their keychain, and tries to restore that state when the app is restarted.

To restore the authentication state, it needs to recheck the credentials with the server, which may take some time. That's why you need to use an auth state listener to pick up this restored state, as shown in the documentation on getting the currently signed in user:

handle = Auth.auth().addStateDidChangeListener { (auth, user) in
  // ...
}

Upvotes: 0

Glenn Posadas
Glenn Posadas

Reputation: 13300

There are multiple ways you can do what you wanna do. Save your data, any kind of data - it's up to you in your local storage, such as:

  1. Defaults
  2. Keychain
  3. Core Data
  4. and whatnot....

Alternatively, in my opinion, you could just try to check the currentUser, like so:

let user = Auth.auth().currentUser

doc: https://firebase.google.com/docs/auth/ios/manage-users

and for javascript: (Authentication State Persistence ) https://firebase.google.com/docs/auth/web/auth-state-persistence

Upvotes: 1

Related Questions