Get Started

Get Started with Passage for Android

If you haven’t already, you'll need to add Passage to your Android project.

Check current auth state

Declare an instance of Passage.

private lateinit var passage: Passage

In your Activity’s onCreate() or Fragment’s onViewCreated method, initialize the Passage instance.

passage = Passage(requireActivity())

When initializing your Activity or Fragment, check to see if the user is currently signed in.

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    passage = Passage(requireActivity())

    ioScope.launch {
        val currentUser = passage.getCurrentUser()
        if (currentUser != null) {
	    // Do authenticated stuff
        } else {
            // Ask user to log in
        }
    }
}

Register new user

The Passage class comes with a convenient, simplified register method that will attempt to:

  • Prompt the user to create a passkey

  • On successful passkey creation, method will create a new user account and return a PassageAuthResult that contains the user’s tokens

  • On a user cancellation or failure of passkey creation, method will use your Passage app’s fallback method (one-time passcode or magic link) and return a PassageAuthFallbackResult that contains the fallback type (otp or magicLink) and an id used for verification.

suspend fun register(identifier: String) {
    try {
        val (authResult, fallbackResult) = passage.register(identifier)
        if (authResult != null) {
            // Account and passkey creation successful! Do authenticated stuff.
        } else if (fallbackResult != null) {
            // Handle one-time passcode or magic link registration
	    handleFallbackAuthResult(fallbackResult)
        }
    } catch (e: PassageException) {
        handleException(e)
    }
}

fun handleFallbackAuthResult(fallbackResult: PassageAuthFallbackResult) {
    when (fallbackResult.method) {
        PassageAuthFallbackMethod.otp -> {
            // User was sent a one time passcode. Navigate to passcode input screen.
            navigateToOTPFragment(fallbackResult.id)
        }
        PassageAuthFallbackMethod.magicLink -> {
            // User was sent a magic link. Navigate to a waiting screen.
            navigateToMagicLinkFragment(fallbackResult.id)
        }
        PassageAuthFallbackMethod.none -> // Prompt user to try passkey again
    }
}

fun handleException(e: PassageException) {
    when (e) {
        is RegisterUserExistsException -> {
            // Alert user to login instead
        }
	is LoginNoExistingUserException -> {
            // Alert user to retry or register instead
        }
    }
}

If you want more granular control or visibility into the passkey flows, we recommend using the Passkey Authentication methods instead.

To learn how to handle the fallback cases shown in the code snippet above, visit Fallback Authentication.

Log in existing user

The Passage class comes with a simplified login method that will attempt to:

  • Prompt the user to login with a passkey

  • On successful passkey login, method will return a PassageAuthResult that contains the user’s tokens

  • On a user cancellation or failure of passkey login, method will use your Passage app’s fallback method (one-time passcode or magic link) and return a PassageAuthFallbackResult that contains the fallback type (otp or magicLink) and an id used for verification.

suspend fun login(identifier: String) {
    try {
        val (authResult, fallbackResult) = passage.login(identifier)
        if (authResult != null) {
            // Do authenticated stuff
        } else if (fallbackResult != null) {
	    // Handle one-time passcode or magic link login
            handleFallbackAuthResult(fallbackResult)
        }
    } catch (e: PassageException) {
        handleException(e)
    }
}

Want more? 🤩

These simplified register and login methods do a lot of heavy lifting for you, but you might want more customized behavior or visibility into the process. If so, let's get into Passkey Authentication!

Last updated

Change request #337: react native