Register or login a user using passkeys on Android
Register a new user with a passkey
To create a new user account with a passkey, pass the user’s email address or phone number to passage.registerWithPasskey:
suspendfunregister(identifier: String) {try { passage.registerWithPasskey(identifier)// passage.getCurrentUser should now return the authenticated userval user = passage.getCurrentUser() ?: return// Do authenticated stuff } catch (e: RegisterWithPasskeyException) {handleRegisterWithPasskeyException(e) }}funhandleRegisterWithPasskeyException(e: RegisterWithPasskeyException) {when (e) {is RegisterWithPasskeyCancellationException -> {// User dismissed native passkey UI prompt }is RegisterWithPasskeyInvalidRequestException -> {// User provided invalid identifier }is RegisterWithPasskeyConfigurationException -> {// There's an issue with your Passage configuration }is RegisterWithPasskeyInterruptedException -> {// The app was interrupted by the OS, try again }is RegisterWithPasskeyCredentialException -> {// Something wrong with the user's passkey } }}
Log in an existing user with a passkey
To log in an existing user with a passkey, pass the user’s email address or phone number to passage.loginWithPasskey:
suspendfunlogin(identifier: String) {try { passage.loginWithPasskey(identifier)// passage.getCurrentUser should now return the authenticated userval user = passage.getCurrentUser() ?: return// Do authenticated stuff } catch (e: LoginWithPasskeyException) {handleLoginWithPasskeyException(e) }}funhandleLoginWithPasskeyException(e: LoginWithPasskeyException) {when (e) {is LoginWithPasskeyCancellationException -> {// User dismissed native passkey UI prompt }is LoginWithPasskeyInvalidRequestException -> {// User provided invalid identifier }is LoginWithPasskeyConfigurationException -> {// There's an issue with your Passage configuration }is LoginWithPasskeyInterruptedException -> {// The app was interrupted by the OS, try again }is LoginWithPasskeyCredentialException -> {// Something wrong with the user's passkey }is LoginWithPasskeyInactiveUserException -> {// User account is no longer active } }}
Autofill passkey login (aka “Conditional UI”)
On your app’s login screen, you can try to surface the user’s passkey without them needing to type in an identifier using the passage.autofillPasskeyLogin method. We recommend attempting this method when the user taps into the email/phone Edit Text component. If the user does not already have a passkey, no passkey prompt will be shown. Here’s an example:
overridefunonViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// ... editText.setOnFocusChangeListener { _, hasFocus ->if (hasFocus) {attemptPasskeyAutofill() } }}funattemptPasskeyAutofill() { ioScope.launch {// If user has a passkey for this app, they'll be prompted to log in with it. passage.autofillPasskeyLogin() ?: return@launch// Do authenticated stuff }}
What's next? ❤️
Your users will LOVE using passkeys. But sometimes you might want to provide fallbacks in the odd case it won't work for them. This is why we provide amazing fallback solutions, too. Read on!