Skip to main content

Overview

OwnID Boost is designed to enhance your existing native login and registration screens by adding OwnID as an add-on. It places OwnID side-by-side with the traditional password field, giving users the option to choose a passwordless experience without altering your current flows.

Prerequisites

Integration Component

1

Create Integration Class

Create a class that implements OwnIdIntegration:
class OwnIdSdkIntegration(
    private val identityPlatform: IdentityPlatform
) : OwnIdIntegration {

    // Registration parameters in addition to user Login ID (optional)
    class IntegrationRegistrationParameters(val name: String) : RegistrationParameters

    override fun register(
        loginID: String,
        params: RegistrationParameters?,
        ownIdResponse: OwnIdResponse,
        callback: OwnIdCallback<Unit>
    ) {
        // Get registration parameters (optional)
        val name = (params as? IntegrationRegistrationParameters)?.name ?: ""

        val ownIdData = ownIdResponse.payload.data

        // Add code that registers user in your identity platform and set OwnID Data to user profile
        // On registration success call: callback(Result.success(Unit))
        // On registration failure call: callback(Result.failure(cause))
    }

    override fun login(
        ownIdResponse: OwnIdResponse,
        callback: OwnIdCallback<Unit>
    ) {
        val data = ownIdResponse.payload.data

        // Add code that logs in user in your identity platform using data
        // On login success call: callback(Result.success(Unit))
        // On login failure call: callback(Result.failure(cause))
    }

    companion object {
        const val CONFIGURATION_FILE: String = "ownIdSdkConfig.json"
        const val PRODUCT_NAME_VERSION: ProductName = "<yourAppName>/<yourAppVersion>" // will be used in the user agent string
    }
}
2

Update Application Class

Update your Application class to use the integration component:
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        // Get an instance of your identity platform integration
        val identityPlatform = ... 

        // Create instance of OwnId with OwnIdSdkIntegration
        OwnId.createInstanceFromFile(
            context = applicationContext,
            configurationAssetFileName = OwnIdSdkIntegration.CONFIGURATION_FILE,
            productName = OwnIdSdkIntegration.PRODUCT_NAME_VERSION,
            ownIdIntegration = { OwnIdSdkIntegration(identityPlatform) }
        )
    }
}

Implementation

Login

The OwnID SDK offers two options to present the passwordless login button:
  • Side-by-side to password field (out-of-the box)
  • Your custom button (you control the UI)
Later, you will learn how to style them.
1

Add the Button to the UI

Side-by-Side button
<com.ownid.sdk.view.OwnIdButton
    android:id="@+id/own_id_login"
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    app:loginIdEditText="@id/et_fragment_login_email" />
2

Listen to Events from OwnID Login View Model

Now that you have added the OwnID UI to your screen, you need to listen to login events that occur as the user interacts with OwnID.First, create an instance of OwnIdLoginViewModel in your Fragment or Activity. Within that Fragment or Activity, insert the code that attaches the OwnIdButton view to the OwnIdLoginViewModel and listens to OwnID Login integration events:
class MyLoginFragment : Fragment() {

    private val ownIdViewModel: OwnIdLoginViewModel by ownIdViewModel()

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

        // To use your own button, instead of the next line see the instructions that come after this code sample
        ownIdViewModel.attachToView(view.findViewById(R.id.own_id_login))

        ownIdViewModel.integrationEvents.observe(viewLifecycleOwner) { ownIdEvent ->
            when (ownIdEvent) {
                // Event when OwnID is busy processing request
                is OwnIdLoginEvent.Busy -> { 
                    // (Optional) Show busy status 'ownIdEvent.isBusy' according to your application UI
                }
                
                // Event when OwnID logs in user
                is OwnIdLoginEvent.LoggedIn -> {
                    // User is logged in with OwnID.
                    // Use 'ownIdEvent.authType' to get type of authentication that was used during OwnID flow.
                }

                is OwnIdLoginEvent.Error -> { 
                    // Handle 'ownIdEvent.cause' according to your application flow 
                    // Check the 'Error Handling' section of this documentation
                }
            }
        }
    }
}
1

Attach your button view to OwnIdLoginViewModel

OwnIdLoginViewModel.attachToView(
    view: View, // An instance of your button view
    owner: LifecycleOwner? = view.findViewTreeLifecycleOwner(), // (optional) A LifecycleOwner for view.
    loginIdProvider: () -> String, // (required) A function that returns user's login identifier (e.g: email) as a [String]. 
)
2

Listen to events from OwnIdLoginViewModel

Now that you have added the OwnID UI to your screen, you need to listen to login events that occur as the user interacts with OwnID.First, create an instance of OwnIdLoginViewModel in your Fragment or Activity. Within that Fragment or Activity, insert the code that attaches your button view to the OwnIdLoginViewModel and listens to OwnID Login integration events:
class MyLoginFragment : Fragment() {

    private val ownIdViewModel: OwnIdLoginViewModel by ownIdViewModel()

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

        // Attach your own button (created in Step 1)
        ownIdViewModel.attachToView(view.findViewById(R.id.your_login_button)) {
            // return the login identifier as a String 
        }

        ownIdViewModel.integrationEvents.observe(viewLifecycleOwner) { ownIdEvent ->
            when (ownIdEvent) {
                // Event when OwnID is busy processing request
                is OwnIdLoginEvent.Busy -> { 
                    // (Optional) Show busy status 'ownIdEvent.isBusy' according to your application UI
                }
                
                // Event when OwnID logs in user
                is OwnIdLoginEvent.LoggedIn -> {
                    // User is logged in with OwnID.
                    // Use 'ownIdEvent.authType' to get type of authentication that was used during OwnID flow.
                }

                is OwnIdLoginEvent.Error -> { 
                    // Handle 'ownIdEvent.cause' according to your application flow 
                    // Check the 'Error Handling' section of this documentation
                }
            }
        }
    }
}

Registration

In the registration flow, the only supported button is side-by-side
Integrate OwnID’s passwordless authentication into your existing registration screen:
1

Add the Button to the UI

Side-by-Side Button
<com.ownid.sdk.view.OwnIdButton
    android:id="@+id/own_id_register"
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    app:loginIdEditText="@id/et_fragment_create_email" />
2

Listen to Events from OwnID Register View Model

Now that you have added the OwnID UI to your screen, you need to listen to registration events that occur as the user interacts with OwnID.First, create an instance of OwnIdRegisterViewModel in your Fragment or Activity. Within that Fragment or Activity, insert the code that attaches the OwnIdButton view to the OwnIdRegisterViewModel and listens to OwnID Register integration events:
class MyRegistrationFragment : Fragment() {

private val ownIdViewModel: OwnIdRegisterViewModel by ownIdViewModel()

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

        ownIdViewModel.attachToView(view.findViewById(R.id.own_id_register))

        ownIdViewModel.integrationEvents.observe(viewLifecycleOwner) { ownIdEvent ->
            when (ownIdEvent) {
                // Event when OwnID is busy processing request
                is OwnIdRegisterEvent.Busy -> {
                    // (Optional) Show busy status 'ownIdEvent.isBusy' according to your application UI 
                }
                
                // Event when user successfully finishes OwnID registration flow
                is OwnIdRegisterEvent.ReadyToRegister -> {
                    // Obtain user's Login ID before calling the register() function.
                    ownIdViewModel.register(loginId)
                    // or 
                    // ownIdViewModel.register(loginId, CustomIntegration.IntegrationRegistrationParameters(name))
                }

                // Event when user select "Undo" option in ready-to-register state
                OwnIdRegisterEvent.Undo -> { /* */}

                // Event when OwnID creates account and logs in user
                is OwnIdRegisterEvent.LoggedIn -> {
                    // User is logged in with OwnID.
                    // Use 'ownIdEvent.authType' to get type of authentication that was used during OwnID flow.
                }

                // Event when an error happened during OwnID flow 
                is OwnIdRegisterEvent.Error -> {
                    // Handle error 'ownIdEvent.cause' according to your application flow
                    // Check the 'Error Handling' section of this documentation
                }
            }
        }
    }
}

Returning Users Experience

In some cases, you might want to start the login flow for returning users programmatically. For example, when a returning user opens the app or opens the login page. For that, you can use the auth() function provided by OwnIdLoginViewModel:
Example
OwnIdLoginViewModel.auth(
    context: Context, // Android context
    onlyReturningUser = true
) : Boolean
The result is returned via OwnIdLoginViewModel.integrationEvents livedata (Represented in Step 2 of Implementing Login section).

Customization

Button Styling

<style name="OwnIdButton.Custom" parent="OwnIdButton.Default">
    <item name="widgetPosition">start</item>
    <item name="showOr">true</item>
    <item name="orTextAppearance">@style/OwnIdButton.OrTextAppearance.Custom</item>
    <item name="backgroundColor">@color/button_background</item>
    <item name="borderColor">@color/button_border</item>
    <item name="iconColor">@color/button_icon</item>
    <item name="showSpinner">true</item>
    <item name="spinnerIndicatorColor">@color/spinner_indicator</item>
    <item name="spinnerTrackColor">@color/spinner_track</item>
</style>

Error Handling

The OwnID SDK provides specific exception classes for handling different types of errors that may occur during the SDK’s operation.
when (error) {
    is OwnIdFlowCanceled -> {
        // User cancelled the OwnID flow
        // Usually safe to ignore this error
        Log.d("OwnID", "Flow cancelled at step: ${error.step}")
    }
    
    is OwnIdUserError -> {
        // Show error.userMessage to the user
        // This message is already localized based on OwnID SDK language settings
        showErrorToUser(error.userMessage)
        Log.e("OwnID", "User error (${error.code}): ${error.message}")
    }
    
    is OwnIdIntegrationError -> {
        // Handle integration error
        // Log for debugging purposes
        Log.e("OwnID", "Integration error: ${error.message}", error.cause)
    }
}