Android SDK

Prev Next

Available in Classic and VPC

This page describes how to use GAMEPOT Android SDK for developing games in Android. You can integrate the game and dashboard by installing the SDK and configuring the environment.

Requirements

The recommended specifications required to use GAMEPOT SDK for Android are as follows:

  • Minimum specifications: Android level 24 or later
    (If you need support for a lower version of Android, please contact Ncloud Support with your request. )

Install SDK and configure environment

You can install the Android SDK, configure the environment, and integrate the game and GAMEPOT dashboard to use features required for the game development.

The GAMEPOT SDK supports the following languages.

  • Korean, English, Italian, Thai, Vietnamese, Japanese, Chinese (Simplified/Traditional), Indonesian, German, Spanish, French

When the app is launched, it is displayed in the supported language in the SDK based on the device's language. If it is an unsupported language, it will be displayed in English.

SDK installation

The following describes how to install GAMEPOT Android SDK and configure a project.

  1. Log in to the dashboard with the admin account.
  2. Add Nbase SDK to the bundle.gradle or bundle.gradle.kts file.
  3. Starting with GAMEPOT 3.0, integrating with external libraries is simple through Gradle configuration.

Set Kotlin Gradle

  1. Add the following definitions to the project's settings.gradle.kts file.
dependencyResolutionManagement {
    repositories {
        ...
        google()
        // nbase repo
        maven(url = "https://repo.nbase.io/repository/nbase-releases")
    }
}
  1. Add the SDK dependencies to the build.gradle.kts file in (Module : app) of the project.
dependencies {
...
    implementation("io.nbase:nbasesdk:latest.release")
}

e.g., When using Google login and Google Play Store payment

 dependencies {
...
    implementation("io.nbase:nbasesdk:latest.release")
    implementation("io.nbase:nbase-adapter-provider-google:latest.release")
    implementation("io.nbase:nbase-adapter-billing-googleplay:latest.release")
}

Set Gradle for Java

  1. Add the definition to the build.gradle file in (Module : project) of the project.
allprojects {
    repositories {
        ...
        google()
        // nbase repo
        maven { url "https://repo.nbase.io/repository/nbase-releases" }
    }
}
  1. Add the SDK dependencies to the build.gradle file in (Module : app) of the project.
dependencies {
...
    implementation("io.nbase:nbasesdk:latest.release")
}

e.g., When using Google login and Google Play Store payment

 dependencies {
...
    implementation("io.nbase:nbasesdk:latest.release")
    implementation("io.nbase:nbase-adapter-provider-google:latest.release")
    implementation("io.nbase:nbase-adapter-billing-googleplay:latest.release")
}

Library list

Name Version Description Dependeny modules
io.nbase:nbasesdk 3.0.87 GAMEPOT base module X
io.nbase:nbase-adapter-provider-google 3.0.10 Google login X
io.nbase:nbase-adapter-provider-apple 3.0.6 Apple login X
io.nbase:nbase-adapter-provider-facebook 3.0.4 Facebook login com.facebook.android:facebook-login:latest.release
io.nbase:nbase-adapter-provider-kakao 3.0.2 Kakao login X
io.nbase:nbase-adapter-provider-line 3.0.2 LINE login X
io.nbase:nbase-adapter-provider-naver 3.0.1 NAVER Login X
io.nbase:nbase-adapter-provider-huawei 3.0.1 Huawei login X
io.nbase:nbase-adapter-provider-playgame 3.0.3 Google Play Games login X
io.nbase:nbase-adapter-provider-x 3.0.1 X login X
io.nbase:nbase-adapter-billing-googleplay 3.0.6 Google Play Store com.android.billingclient:billing-ktx:6.1.0
io.nbase:nbase-adapter-billing-onestore 3.0.2 ONE Store X
io.nbase:nbase-adapter-billing-galaxy 3.0.3 Galaxy Store X
io.nbase:nbase-adapter-billing-huawei 3.0.1 Huawei Store X

Guest login is applied to the base module.

Preparation

  1. Copy the project ID and project key from Dashboard > Project settings.
  2. Configure login, store, and integration settings in Dashboard > Project settings.
  3. See Configuration by login method for each login, set it in the console and add it to the dashboard.
  4. For in-app payment, see Configuration by store to set it in the console and add it to the dashboard.
  5. Register items for each store for in-app payment. Add them in Dashboard > Payment > In-app .

Reset

To perform an initialization, add the following code to the object used in the first scene loaded when the game starts.

Kotlin:

import com.nbase.sdk.NBase
import com.nbase.sdk.Store

NBase.initialize(activity, projectId, projectKey, [StoreId], [language], [region]) { init, e ->
    if (e != null) {
        Log.e("NBase", e.message)
    } else {
        Log.e("NBase", init)
    }
}

Java:

import com.nbase.sdk.NBase;
import com.nbase.sdk.Store;

NBase nBase = NBase.INSTANCE;
nBase.initialize(activity, projectId, projectKey, Store.GOOGLE, language, region, (init, e) -> {
    if (e != null) {
        Log.e("NBase", "initialize fail: " + e.getMessage());
    } else {
        Log.e("NBase", "initialize success: " + init.toString());
    }
    return null;
});
  • Parameter
Key Type Description Required
projectId String Project ID (Dashboard → Project settings) O
projectKey String Project key (Dashboard → Project settings) O
storeId String Store ID (See the following table) O
language String Language (en, ko, jp...) O
region String Region name (kr, jp, sg, us, eu, preview) O
Key Description
Store.GOOGLE Google Play Store
Store.ONE ONE Store
Store.GALAXY Galaxy Store
Store.AMAZON Amazon Store
Store.HUAWEI Huawei Store
  • Callback
Key Type Description
status Boolean Condition
language String Language
country String Country
remote_ip String IP
platform String Platform
sandbox Boolean Sandbox status

Login feature

Use login feature

Use the following code to use the SDK login feature that functions when clicking the login button according to the login UI implemented by the developer.

Kotlin:

import com.nbase.sdk.Provider

NBase.signIn(activity, Provider.GOOGLE.toString()) { user, e -> 
    if (e != null) {
        if (e.errorCode == 414) { // Maintenance
            // Maintenance
            Log.e("NBase", "Maintenance: " + e.message) // Maintenance message
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, user?.appStatus) { status, err ->
                // Popup handling
            }
            */
        } else if (e.errorCode == 413) { // Update
            // Update
            Log.e("NBase", "Update: " + e.message) // Update message
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, user?.appStatus) { status, err ->
                // Popup handling
            }
            */
        } else {
            // signIn Failed
            Log.e("NBase", "signIn Failed: " + e.errorCode + ", " + e.message)
        }
    } else {
        // signIn Success
        Log.e("NBase", "signIn Success: " + user.toString())
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    NBase.onActivityResult(requestCode, resultCode, data)
}

Java:

import com.nbase.sdk.Provider;

NBase nBase = NBase.INSTANCE;

nBase.signIn(activity, Provider.GOOGLE.toString(), (user, e) -> {
    if (e != null) {
        if (e.getErrorCode() == 414) { // Maintenance
            // Maintenance
            Log.e("NBase", "Maintenance: " + e.getMessage()) // Maintenance message
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, user?.appStatus, (status, err) -> {
                // Popup handling
            }
            */
        } else if (e.getErrorCode() == 413) { // Update
            // Update
            Log.e("NBase", "Update: " + e.getMessage()) // Update message
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, user?.appStatus, (status, err) -> {
                // Popup handling
            }
            */
        } else {
            // signIn Failed
            Log.e("NBase", "signIn Failed: " + e.getErrorCode() + ", " + e.getMessage());
        }
    } else {
        // signIn Success
        Log.e("NBase", "signIn Success: " + user.toString());
    }
    return null;
});

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    nBase.onActivityResult(requestCode, resultCode, data);
}

If you use the pop-up provided by the SDK when updating or checking, add the following code.

Kotlin:

NBase.showAppStatusPopup(activity, appStatus){ status, e ->
    if (status.close){
        // App Close
    }
    else if (status.next){
        // Next, Optional update
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.showAppStatusPopup(activity, appStatus){ status, e ->
    if (status.getClose()){
        // App Close
    }
    else if (status.getNext()){
        // Next, Optional update
    }
}
  • Parameter
Key Description
Provider.GOOGLE Google
Provider.ANONYMOUS Guest
Provider.FACEBOOK Facebook
Provider.APPLE Apple
Provider.KAKAO Kakao
Provider.GOOGLEPLAY Google Play Games
Provider.STEAM Steam
Provider.X X
Provider.LINE LINE
Provider.NAVER NAVER
Provider.GITHUB GitHub
Provider.MICROSOFT Microsoft
Provider.HUAWEI Huawei
  • User
Key Type Description
id string User's unique ID
socialId string Social ID
name string Name (if provided)
email string Email (if provided)
token string Token
age int Age (if provided)
profile string Profile (if provided)
customField string Custom field
isSignUp bool Registration status
appStatus AppStatus Maintenance/update status
  • AppStatus
Key Type Description
message string Message
startedAt long Start Time
endedAt long Exit time
currentAppVersion string Current app version
updateAppVersion string Update app version
currentAppVersionCode string Current app version code
updateAppVersionCode string Update app version code
isForce bool Whether to force update
url string URL registered for maintenance/update

Login UI provided by SDK

You can use the login UI provided by GAMEPOT SDK in a completed form.
Use the following code to call the login UI provided by the SDK.

Kotlin:

NBase.openSignInUI(activity) { user, e -> 
    if (e != null) {
        if (e.errorCode == 414) { // Maintenance
            // Maintenance
            Log.e("NBase", "Maintenance: " + e.message) // Maintenance message
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, user?.appStatus) { status, err ->
                // Popup handling
            }
            */
        } else if (e.errorCode == 413) { // Update
            // Update
            Log.e("NBase", "Update: " + e.message) // Update message
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, user?.appStatus) { status, err ->
                // Popup handling
            }
            */
        } else {
            // signIn Failed
            Log.e("NBase", "signIn Failed: " + e.errorCode + ", " + e.message)
        }
    } else {
        // signIn Success
        Log.e("NBase", "signIn Success: " + user.toString())
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.openSignInUI(activity, (user, e) -> {
    if (e != null) {
        if (e.getErrorCode() == 414) { // Maintenance
            // Maintenance
            Log.e("NBase", "Maintenance: " + e.getMessage()) // Maintenance message
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, user?.appStatus, (status, err) -> {
                // Popup handling
            }
            */
        } else if (e.getErrorCode() == 413) { // Update
            // Update
            Log.e("NBase", "Update: " + e.getMessage()) // Update message
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, user?.appStatus, (status, err) -> {
                // Popup handling
            }
            */
        } else {
            // signIn Failed
            Log.e("NBase", "signIn Failed: " + e.getErrorCode() + ", " + e.getMessage());
        }
    } else {
        // signIn Success
        Log.e("NBase", "signIn Success: " + user.toString());
    }
    return null;
});

Auto login (optional)

After initialization, it will attempt to automatically log in with the last authentication method you logged in with. We recommend checking the last login provider type before attempting automatic login and only performing automatic login when a valid value is present.

Kotlin:

// Check the last login provider type.
val lastProviderType = NBase.getLastProviderType()

if (lastProviderType != Provider.NONE) {
    // Attempt automatic login only when a valid provider is available.
    NBase.signInLastLoggedIn(activity) { user, e ->
        if (e != null) {
            if (e.errorCode == 414) { // Maintenance
                // Maintenance
                Log.e("NBase", "Maintenance: " + e.message) // Maintenance message
                /* case 1: Use in-game popup implemented directly by the developer
                case 2: Call the code below to use the SDK's own popup
                NBase.showAppStatusPopup(activity, user?.appStatus) { status, err ->
                    // Popup handling
                }
                */
            } else if (e.errorCode == 413) { // Update
                // Update
                Log.e("NBase", "Update: " + e.message) // Update message
                /* case 1: Use in-game popup implemented directly by the developer
                case 2: Call the code below to use the SDK's own popup
                NBase.showAppStatusPopup(activity, user?.appStatus) { status, err ->
                    // Popup handling
                }
                */
            } else {
                // signIn Failed
                Log.e("NBase", "signIn Failed: " + e.errorCode + ", " + e.message)
            }
        } else {
            // signIn Success
            Log.e("NBase", "signIn Success: " + user.toString())
        }
    }
} else {
    // No last login information
    Log.e("NBase", "No last login provider found")
}

Java:

NBase nBase = NBase.INSTANCE;

// Check the last login provider type.
Provider lastProviderType = nBase.getLastProviderType();

if (lastProviderType != Provider.NONE) {
    // Attempt automatic login only when a valid provider is available.
    nBase.signInLastLoggedIn(activity, (user, e) -> {
        if (e != null) {
            if (e.getErrorCode() == 414) { // Maintenance
                // Maintenance
                Log.e("NBase", "Maintenance: " + e.getMessage()) // Maintenance message
                /* case 1: Use in-game popup implemented directly by the developer
                case 2: Call the code below to use the SDK's own popup
                NBase.showAppStatusPopup(activity, user?.appStatus, (status, err) -> {
                    // Popup handling
                }
                */
            } else if (e.getErrorCode() == 413) { // Update
                // Update
                Log.e("NBase", "Update: " + e.getMessage()) // Update message
                /* case 1: Use in-game popup implemented directly by the developer
                case 2: Call the code below to use the SDK's own popup
                NBase.showAppStatusPopup(activity, user?.appStatus, (status, err) -> {
                    // Popup handling
                }
                */
            } else {
                // signIn Failed
                Log.e("NBase", "signIn Failed: " + e.getErrorCode() + ", " + e.getMessage());
            }
        } else {
            // signIn Success
            Log.e("NBase", "signIn Success: " + user.toString());
        }
        return null;
    });
} else {
    // No last login information
    Log.e("NBase", "No last login provider found");
}
  • getLastProviderType()

Return the last logged in provider type.

Return Type Description
Provider Last login provider type
  • signInLastLoggedIn() Parameter
Key Type Description Required
activity Activity Current activity O

Log out

Use the following code to use the SDK logout feature.

Kotlin:

NBase.signOut(activity) { status, e ->
    if (e != null) {
        Log.e("NBase", "signOut Fail")
        Log.e("NBase", "error.message : " + e.message.toString())
    } else {
        Log.e("NBase", "signOut")
        Log.e("NBase", "status : " + status.toString())
        // Processing logic after successful logout
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.signOut(activity, (status, e) -> {
    if (e != null) {
        Log.e("NBase", "signOut Fail");
        Log.e("NBase", "error.message : " + e.getMessage());
    } else {
        Log.e("NBase", "signOut");
        Log.e("NBase", "status : " + status.toString());
        // Processing logic after successful logout
    }
    return null;
});
  • Parameter
Key Type Description Required
activity Activity Current activity O
  • Callback
Key Type Description
status Boolean Success or Failure

Withdraw from membership

Use the following code to use the membership withdrawal feature.

Kotlin:

NBase.deleteMember(providerId) { status, e ->
    if (e != null) {
        Log.e("NBase", "deleteMember Fail")
        Log.e("NBase", "error.message : " + e.message.toString())
    } else {
        Log.e("NBase", "deleteMember")
        Log.e("NBase", "status : " + status.toString())
        // Logic after successful membership withdrawal
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.deleteMember(providerId, (status, e) -> {
    if (e != null) {
        Log.e("NBase", "deleteMember Fail");
        Log.e("NBase", "error.message : " + e.getMessage());
    } else {
        Log.e("NBase", "deleteMember");
        Log.e("NBase", "status : " + status.toString());
        // Logic after successful membership withdrawal
    }
    return null;
});
  • Parameter
Key Type Description Required
providerId Provider Logged-in provider type (example: Provider.GOOGLE, Provider.ANONYMOUS, etc.) O
  • Callback
Key Type Description
status Boolean Success or Failure

Authenticate with ID and password (optional)

This is an authentication method that allows users to log in using their email address and password. It performs user authentication based on the user's email address and password. This feature plays an important role in traditional email/password-based authentication systems.

Kotlin:

NBase.signInWithPassword(activity, username, password) { user, e ->
    if (e != null) {
        Log.e("NBase", e.message)
    } else {
        Log.e("NBase", user)
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.signInWithPassword(activity, username, password, (user, e) -> {
    if (e != null) {
        Log.e("NBase", "signInWithPassword fail: " + e.getMessage());
    } else {
        Log.e("NBase", "signInWithPassword success: " + user.toString());
    }
    return null;
});

Log in with credentials (optional)

This is used to process user logins with authentication credentials obtained through various authentication methods (email and password, social media account, phone number, etc.). It helps you easily implement different authentication methods and allows you to log in to GAMEPOT.

Kotlin:

NBase.signInWithCredential(activity, Provider.GOOGLE.ToString(), providerToken) { user, e ->
    if (e != null) {
        Log.e("NBase", e.message)
    } else {
        Log.e("NBase", user)
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.signInWithCredential(activity, Provider.GOOGLE.toString(), providerToken, (user, e) -> {
    if (e != null) {
        Log.e("NBase", "signInWithCredential fail: " + e.getMessage());
    } else {
        Log.e("NBase", "signInWithCredential success: " + user.toString());
    }
    return null;
});

External account integration feature

Use external account integration feature

Use the following code to integrate another social account with your current GAMEPOT user account.

Kotlin:

NBase.createLinking(activity, providerId) { linkingId, e ->
    if (e != null) {
        Log.e("NBase", "createLinking Fail")
        Log.e("NBase", "error.message : " + e.message.toString())
    } else {
        Log.e("NBase", "createLinking")
        Log.e("NBase", "linkingId : " + linkingId.toString())
        // Processing logic after successful account integration
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.createLinking(activity, providerId, (linkingId, e) -> {
    if (e != null) {
        Log.e("NBase", "createLinking Fail");
        Log.e("NBase", "error.message : " + e.getMessage());
    } else {
        Log.e("NBase", "createLinking");
        Log.e("NBase", "linkingId : " + linkingId);
        // Processing logic after successful account integration
    }
    return null;
});
  • Parameter
Key Type Description Required
activity Activity Current activity O
providerId Provider Provider type to integrate (example: Provider.GOOGLE, Provider.FACEBOOK, etc.) O
  • Callback
Key Type Description
linkingId String Integration ID returned when integration is successful

Check integration list

Use the following code to check the list of social accounts currently integrated with your GAMEPOT user account.

Kotlin:

NBase.getLinkedLists { linkings, e ->
    if (e != null) {
        Log.e("NBase", "getLinkedLists Fail")
        Log.e("NBase", "error.message : " + e.message.toString())
    } else {
        Log.e("NBase", "getLinkedLists")
        Log.e("NBase", "linkings : " + linkings.toString())
        // Processing logic after checking the integration list
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.getLinkedLists((linkings, e) -> {
    if (e != null) {
        Log.e("NBase", "getLinkedLists Fail");
        Log.e("NBase", "error.message : " + e.getMessage());
    } else {
        Log.e("NBase", "getLinkedLists");
        Log.e("NBase", "linkings : " + linkings.toString());
        // Processing logic after checking the integration list
    }
    return null;
});
  • Callback
Key Type Description
linkings List List of integrated accounts
  • Linking
Key Type Description
id String Integration ID (use when removing account integration)
username String Social ID
provider String Social provider type

Remove integration

To remove a specific social account integration from your current GAMEPOT user account, use the following code.

Kotlin:

NBase.deleteLinking(linkingId) { status, e ->
    if (e != null) {
        Log.e("NBase", "deleteLinking Fail")
        Log.e("NBase", "error.message : " + e.message.toString())
    } else {
        Log.e("NBase", "deleteLinking")
        Log.e("NBase", "status : " + status.toString())
        // Processing logic after successful integration removal
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.deleteLinking(linkingId, (status, e) -> {
    if (e != null) {
        Log.e("NBase", "deleteLinking Fail");
        Log.e("NBase", "error.message : " + e.getMessage());
    } else {
        Log.e("NBase", "deleteLinking");
        Log.e("NBase", "status : " + status.toString());
        // Processing logic after successful integration removal
    }
    return null;
});
  • Parameter
Key Type Description Required
linkingId String Integration ID to remove (obtained from createLinking or getLinkedLists) O
  • Callback
Key Type Description
status Boolean Success or Failure

Check app status

Use the following code to check the current client's maintenance/update status.

Kotlin:

NBase.checkAppStatus(activity) { status, error ->
    when (status) {
        is NBaseAppStatus.Maintenance -> {
            // Maintenance
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, status) { popupStatus, e ->
                // Popup handling
            }
            */
        }
        is NBaseAppStatus.Update -> {
            // Update
            /* case 1: Use in-game popup implemented directly by the developer
            case 2: Call the code below to use the SDK's own popup
            NBase.showAppStatusPopup(activity, status) { popupStatus, e ->
                // Popup handling
            }
            */
        }
        null -> {
            // AppStatus Success or Error
            if (error != null) {
                Log.e("NBase", "checkAppStatus error: $error")
            } else {
                Log.e("NBase", "checkAppStatus success")
            }
        }
    }
}

Java:

NBase nBase = NBase.INSTANCE;

nBase.checkAppStatus(activity, (status, error) -> {
    if (status instanceof NBaseAppStatus.Maintenance) {
        // Maintenance
        /* case 1: Use in-game popup implemented directly by the developer
        case 2: Call the code below to use the SDK's own popup
        nBase.showAppStatusPopup(activity, status, (popupStatus, e) -> {
            // Popup handling
        });
        */
    } else if (status instanceof NBaseAppStatus.Update) {
        // Update
        /* case 1: Use in-game popup implemented directly by the developer
        case 2: Call the code below to use the SDK's own popup
        nBase.showAppStatusPopup(activity, status, (popupStatus, e) -> {
            // Popup handling
        });
        */
    } else if (status == null) {
        // AppStatus Success or Error
        if (error != null) {
            Log.e("NBase", "checkAppStatus error: " + error.toString());
        } else {
            Log.e("NBase", "checkAppStatus success");
        }
    }
    return null;
});

Troubleshooting

Q. The following error occurs in Android.

Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.security.crypto.MasterKeys" on path: DexPathList[[zip file "/data/app/~~KKBtt9efgPjpqDSP6o3P1g==/com.nbase.je_beta-6fz3RrA1gqu27fSFW0ehcQ==/base.apk"],nativeLibraryDirectories=[/data/app/~~KKBtt9efgPjpqDSP6o3P1g==/com.nbase.je_beta-6fz3RrA1gqu27fSFW0ehcQ==/lib/arm64, /system/lib64, /system/system_ext/lib64]]

A. This error is caused by not finding the MasterKeys class, and you need to enter the following code in the build.gradle or build.gradle.kt file.

implementation("androidx.security:security-crypto:1.0.0")

Q. The following error occurs during Google login.

10: Developer console is not set up correctly.

A. You need to check whether the OAuth 2.0 client ID and client secret of the web application registered in Google Cloud Console are entered correctly in the GAMEPOT dashboard.

Q. The following error occurs during Google login.

16: Cannot find a matching credential.

A. This error occurs when the SHA-1 value of the app and the package registered with the OAuth 2.0 client ID of the Android type in Google Cloud Console are different.