📦 SwiftyLaunch Modules
🔐 AuthKit
Overview

AuthKit Module Overview

SwiftyLaunch Module - AuthKit

Powered by Firebase Authentication

AuthKit wraps Firebase Authentication SDK to allow you to create apps with authentication without having to worry about writing thousands of lines of boilerplate code.

AuthKit is bundled together with DBKit and is referenced to as FirebaseKit within the apps generated via SwiftyLaunch.

After generating a project with AuthKit enabled and completing the initial project setup, you will get following features out of the box:

  • A complete Email Sign-In flow: Complete authentication flow including account creation, email verification, password reset, and more. Read more.
  • A complete Sign-In With Apple flow: Complete authentication flow for using Sign In With Apple. Read more.
  • Ability to lock actions to only signed-in users: Lock features behind a paywall and show the paywall when the user tries to access them. Read more.
  • Ability to lock views to only signed-in: Lock views behind a paywall and show the paywall when the user tries to access them. Read more.
  • Account settings in the app settings screen: A dedicated view in the app settings screen to manage the user account. Read more.
  • Integration with other modules: If the user is signed in, the firebase user ID will be shared among other providers as well. Read more.
  • (AnalyticsKit only) Automatic analytics tracking: Automatically track events related to authentication. Read more.
  • (BackendKit only) BackendKit integration: You can also access AuthKit information on the backend. Read more.

Module Deep Dive

Initialization and Configuration

  1. We initilize FirebaseKit (AuthKit + DBKit) in App.swift: by calling a static function DB.initFirebase()
  2. After application launch we attach an authentication state change listener, to connect firebase user ID with other providers when the user signs in, and remove the alias when the user signs out. Read more.
  3. We initialize the DB object in App.swift and attach it to the root view as an environment object to be shared across the app. Read more.
  4. During DB initialization, we attach an internal authentication state listener (registerAuthStateListener()) that listens for the user sign-in and sign-out events and updates currentUser and authState variables accordingly. Read below for information on how to access these variables.

General Usage

The DB object was designed to be used as an EnvironmentObject throughout the application and is attached to the root of the view hierarchy in App.swift. By default, we use the abbreviation db for the environment object.

Here are some of the relevant AuthKit-related DB object parameters and functions that you can access:

Access Authentication State

FirebaseBackend.swift
@Published public var authState: AuthState = .signedOut

Can either be .signedOut, .signedIn or signedInUnverified (means that the user created an account but hasn't verified the email address yet, not applicable for Sign In With Apple). Updated automatically by the registerAuthStateListener() listener that is called during initialization.

Access User Data

FirebaseBackend.swift
@Published public var currentUser: User? = nil

Contains information about the currently signed-in user, such as his name, email address or id. Read more info here (opens in a new tab). Updated automatically by the registerAuthStateListener(). Nil if the user is signed out.

Show Sign-In Sheet

ShowSignInSheetWhenCalledModifier.swift
public func showSignInSheet() { }

A DB function that will show the sign-in sheet. The function sends a notification to the notification center while the view modifier placed in App.swift called ShowSignInSheetWhenCalledModifier() listens to that notification and presents the sheet with the SignInView.

Execute if User is Signed In

FirebaseBackend.swift
public func executeIfSignedIn(otherwise consequence: NotSignedInConsequence = .showInAppNotification, _ closure: () -> Void) { }

A function that that executes the provided closure if the user is logged in. If the user is not logged in, the consequence parameter will determine what happens next. (Will either show the sign in sheet or show an in-app notification saying that the feature required them to log in). Read more in the Lock Actions to Signed-In Users section.

Has an analagous function that will also take in withUserID as a parameter, which will only execute the closure if the user is signed in and has a specific user ID.

Both come in sync and async versions.

Show View if User is Logged in

requirePremium.swift
public func requireLogin(
    db: DB,
    navTitle: LocalizedStringKey = "",
    onCancel: @escaping () -> Void
) -> some View { }

A view modifier that allows you to lock views behind the sign in view. If the user is logged, the view will be shown as usual, otherwise the SignInView will be shown. Read more in the Lock Views to Signed-In Users section.

Integration with other Modules

Depending on your module selection during project generation, you will have to deal with multiple different module providers, such as RevenueCat for InAppPurchaseKit, or PostHog for AnalyticsKit. All of these providers have their own ways of identifying users within their system, which works great in isolation, but can be a bit cumbersome when you have to deal with multiple providers at once. Juggling multiple user IDs accross multiple providers sounds like a nightmare, so we've made it easier for you.

During the initialization of your application, we attach an authentication state listener, which listens for the user sign-in and sign-out events. When the user signs in, we automatically take the Firebase User ID of the signed-in user and add it as an alias ID for other providers. This way, you can you can use a single user ID across multiple providers. When the user signes out, we automatically remove the alias.

App.swift
// ...
Auth.auth().addStateDidChangeListener { (auth, user) in
    if let firebaseUser = user, firebaseUser.isEmailVerified {
        // ...
        PushNotifications.associateUserWithID(firebaseUser.uid)
        InAppPurchases.associateUserWithID(firebaseUser.uid, currentUserProperties: /* ... */)
        Analytics.associateUserWithID(firebaseUser.uid, userProperties: /* ... */)
        // ...
    } else {
        Analytics.removeUserIDAssociation()
        InAppPurchases.removeUserIDAssociation()
        PushNotifications.removeUserIDAssociation()
    }
}
// ...

AnalyticsKit Integration

If AnalyticsKit is selected during project generation, info events and errors related to authentication are automatically tracked with auth as the source.

Module File Contents

Let's go through every file that is contained in the FirebaseKit module that is related to AuthKit (also includes DBKit or BackendKit related items):

Config

Contains the GoogleService-Info.plist file that you downloaded from the Firebase Console during project setup.

Sources / Model

FirebaseBackend.swift

Contains the DB observable class, which is the entry point to interact with DatabaseKit and AuthKit.

Errors.swift

Contains the AuthKitError enum that is used to represent user-facing errors that can occur during the authentication process.

Sources / View / Auth

AccountSettingsView.swift

View that can contains account-related settings in the app. See Account Settings for more information.

ReAuthSheet.swift

Contains a ReAuthView view that is shown in a slide over sheet (opens in a new tab) that prompts the user to re-authenticate before performing a sensitive action.

SignInFlow / SignInView.swift

The root view of the sign-in flow. From here, users can enter their email and password to sign in, sign in with Apple, or navigate to the sign-up (SignUpView) or password reset views (ForgotPasswordView).

SignInFlow / SignUpView.swift

The view that allows the user to sign up with an email and password. Contains also a password strength checker. On completion, will create an account, send a verification email to the user and navigate to the email verification view (VerifyEmailView).

SignInFlow / ForgotPasswordView.swift

The view that allows the user to reset their password. The user will enter their email, and if the email is valid, a password reset email will be sent.

SignInFlow / VerifyEmailView.swift

The view that is shown after the user has signed up but has not yet verified their email. The user can request a new verification email after 60 seconds or sign out.

SignInFlow / Components / EmailInputFields.swift

Contains the input fields for the email and password that are used in the sign-in view (SignInView), sign-up view (SignUpView), new password view in the account settings view (AccountSettingsView), and re-auth view (ReAuthView).

Sources / ViewModifier

ShowSignInSheetWhenCalledModifier.swift

Exposes the ShowSignInSheetWhenCalledModifier() view modifier that listens for the showSignInSheet() notification and presents the sign-in sheet. Because we only use it in the root view in App.swift, we don't wrap it around a more general view modifier, and attach it via .modifier(ShowSignInSheetWhenCalledModifier()).

requireLogin.swift

Exposes the .requireLogin() view modifier that allows you to lock views to only authenticated users. See Lock Views behind Auth for more information.

visibleOnlyToUserWithID.swift

Exposes the .visibleOnlyToUserWithID() view modifier that allows you to lock views to only authenticated users with a specific user id. See Lock Views behind Auth for more information.

Sources / Extensions

String+Extensions.swift

Contains extensions related to string validation during auth flow. Email validation, password validation, etc.