Skip to content

Commit

Permalink
refactor(console): polish android guide
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoyijun committed Jun 28, 2024
1 parent 07e3725 commit 6a4ed96
Showing 1 changed file with 72 additions and 127 deletions.
199 changes: 72 additions & 127 deletions packages/console/src/assets/docs/guides/native-android/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import UriInputField from '@/mdx-components/UriInputField';
import InlineNotification from '@/ds-components/InlineNotification';
import Steps from '@/mdx-components/Steps';
import Step from '@/mdx-components/Step';
import RedirectUrisNative from '../../fragments/_redirect-uris-native.mdx';
import Checkpoint from '../../fragments/_checkpoint.md';

<Steps>

Expand All @@ -14,48 +16,46 @@ import Step from '@/mdx-components/Step';

Before you install Logto Android SDK, ensure `mavenCentral()` is added to your repository configuration in the Gradle project build file:

```kotlin
dependencyResolutionManagement {
<Code title="settings.gradle.kts" className="language-kotlin">
{`dependencyResolutionManagement {
repositories {
mavenCentral()
}
}
```
}`}
</Code>

Add Logto Android SDK to your dependencies:

```kotlin
dependencies {
<Code title="build.gradle.kts" className="language-kotlin">
{`dependencies {
implementation("io.logto.sdk:android:1.1.3")
}
```
}`}
</Code>

Since the SDK needs internet access, you need to add the following permission to your `AndroidManifest.xml` file:

```xml
<?xml version="1.0" encoding="utf-8"?>
<Code title="AndroidManifest.xml" className="language-xml">
{`<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- add internet permission -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- other configurations... -->
</manifest>
```
</manifest>`}
</Code>


</Step>

<Step
title="Init LogtoClient"
subtitle="1 step"
>
<Step title="Init LogtoClient">

<InlineNotification>We use Kotlin in this example, but the concepts are the same for Java.</InlineNotification>

Create a `LogtoViewModel.kt` and init `LogtoClient` in this view model:

<Code className="language-kotlin">
<Code title="LogtoViewModel.kt" className="language-kotlin">
{`//...with other imports
import io.logto.sdk.android.LogtoClient
import io.logto.sdk.android.type.LogtoConfig
Expand Down Expand Up @@ -89,22 +89,19 @@ class LogtoViewModel(application: Application) : AndroidViewModel(application) {

then, create a `LogtoViewModel` for your `MainActivity.kt`:

```kotlin
//...with other imports
<Code title="MainActivity.kt" className="language-kotlin">
{`//...with other imports
class MainActivity : AppCompatActivity() {
private val logtoViewModel: LogtoViewModel by viewModels { LogtoViewModel.Factory }
//...other codes
}
```
}`}
</Code>

</Step>

<Step
title="Implement sign-in"
subtitle="2 steps"
>
<Step title="Configure redirect URI">

Before starting, you need to add a redirect URI in the Admin Console for your application.
<RedirectUrisNative defaultUri="io.logto.android://io.logto.sample/callback"/>

In Android, the redirect URI follows the pattern: `$(LOGTO_REDIRECT_SCHEME)://$(YOUR_APP_PACKAGE)/callback`:

Expand All @@ -113,95 +110,15 @@ In Android, the redirect URI follows the pattern: `$(LOGTO_REDIRECT_SCHEME)://$(

Assuming you treat `io.logto.android` as the custom `LOGTO_REDIRECT_SCHEME`, and `io.logto.sample` is your app package name, the Redirect URI should be `io.logto.android://io.logto.sample/callback`.

You can add the redirect URI in the following input field:

<UriInputField name="redirectUris" />

After the redirect URI is configured, we add a `signIn` method to your `LogtoViewModel.kt`, which will call `logtoClient.signIn` API to invoke the Logto sign-in page:

<Code className="language-kotlin">
{`//...with other imports
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// ...other codes
fun signIn(context: Activity) {
logtoClient.signIn(context, "${props.redirectUris[0] ?? '<your-redirect-uri>'}") { logtoException ->
logtoException?.let { println(it) }
}
}
}`}
</Code>

Now setup on-click listener for the sign-in button in your `MainActivity.kt` to call the `signIn` method:

```kotlin
//...with other imports
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//...other codes

// Assume you have a button with id `sign_in_button` in your layout
val signInButton = findViewById<Button>(R.id.sign_in_button)
signInButton.setOnClickListener {
logtoViewModel.signIn(this)
}
}
}
```

</Step>

<Step
title="Implement sign-out"
subtitle="1 step"
>

Similar to sign-in, we add a `signOut` method to `LogtoViewModel.kt` to call `logtoClient.signOut` API:
<Step title="Implement sign-in and sign-out">

```kotlin
//...with other imports
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// ...other codes
fun signOut() {
logtoClient.signOut { logtoException ->
logtoException?.let { println(it) }
}
}
}
```
After the redirect URI is configured, we can use `logtoClient.signIn` to sign in the user and `logtoClient.signOut` to sign out the user.

After you signed out, the Logto SDK will clear all local credentials even though Logto exceptions occurred when calling `logtoClient.signOut` API.
Now let's use them in your `LogtoViewModel.kt`:

Then, we can add a button to call the `signOut` method in `MainActivity.kt`:

```kotlin
//...with other imports
class MainActivity : AppCompatActivity() {
//...other codes
override fun onCreate(savedInstanceState: Bundle?) {
//...other codes
//...sign-in button codes

// Assume you have a button with id `sign_out_button` in your layout
val signOutButton = findViewById<Button>(R.id.sign_out_button)
signOutButton.setOnClickListener {
logtoViewModel.signOut()
}
}
}
```

</Step>

<Step
title="Handle authentication status"
subtitle="1 step"
>

In Logto SDK, we can use `logtoClient.isAuthenticated` to check the authentication status, if the user is signed in, the value will be `true`, otherwise, the value will be `false`.

Now, let's add a live data to `LogtoViewModel.kt` to observe the authentication status, and update the status when the user signed in or signed out:

<Code className="language-kotlin">
<Code title="LogtoViewModel.kt" className="language-kotlin">
{`//...with other imports
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// ...other codes
Expand Down Expand Up @@ -229,19 +146,29 @@ class LogtoViewModel(application: Application) : AndroidViewModel(application) {
}`}
</Code>

Then, we observe the `authenticated` live data in `MainActivity.kt`, when the user is signed in, we hide the sign-in button and show the sign-out button and vice versa:
Now setup on-click listener for the sign-in button and sign-out button in your `MainActivity.kt`:

```kotlin
//...with other imports
<Code title="MainActivity.kt" className="language-kotlin">
{`//...with other imports
class MainActivity : AppCompatActivity() {
//...other codes
override fun onCreate(savedInstanceState: Bundle?) {
//...other codes
// Assume you have a button with id "sign_in_button" in your layout
val signInButton = findViewById<Button>(R.id.sign_in_button)
signInButton.setOnClickListener {
logtoViewModel.signIn(this)
}
// Assume you have a button with id "sign_out_button" in your layout
val signOutButton = findViewById<Button>(R.id.sign_out_button)
// ...handle button click codes
signOutButton.setOnClickListener {
if (logtoViewModel.authenticated) { // Check if the user is authenticated
logtoViewModel.signOut()
}
}
// Observe the authentication status
// Observe the authentication status to update the UI
logtoViewModel.authenticated.observe(this) { authenticated ->
if (authenticated) {
// The user is authenticated
Expand All @@ -253,23 +180,41 @@ class MainActivity : AppCompatActivity() {
signOutButton.visibility = View.GONE
}
}
}
}
```
}`}
</Code>

</Step>

<Step
title="Checkpoint: Test your application"
subtitle="1 step"
>
<Step title="Checkpoint: Test your app">

<Checkpoint />

</Step>

Now, you can test your application:

1. Run your application, you will see the sign-in button.
2. Click the sign-in button, the Logto SDK will navigate to the Logto sign-in page.
3. After you signed in, you will be redirect back to your application and see the sign-out button.
4. Click the sign-out button, you will see the sign-in button again.
<Step title="Display user information">

To display the user's information, you can use the `getIdTokenClaims` method to get user information. For example, in a Android app:

<Code title="LogtoViewModel.kt" className="language-kotlin">
{`//...with other imports
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// ...other codes
// Add a live data to observe the id token claims
private val _idTokenClaims = MutableLiveData<IdTokenClaims>()
val idTokenClaims: LiveData<IdTokenClaims>
get() = _idTokenClaims
fun getIdTokenClaims() {
logtoClient.getIdTokenClaims { logtoException, idTokenClaims ->
logtoException?.let { _logtoException.postValue(it) } ?: _idTokenClaims.postValue(idTokenClaims)
}
}
}`}
</Code>

</Step>

Expand Down

0 comments on commit 6a4ed96

Please sign in to comment.