Skip to content

Login logout

Login in authentication consists of the following steps.

Note
  • Versions below SDK 4.7.0 do not support Helper. Please refer to [the following] for the existing login application method.
  • For a description of AuthV4.Helper, please refer to the Authentication page.

Login

Login in authentication consists of the following steps.

  1. Automatic Login and Implicit Login
  2. Explicit Login
  3. Check IdP Account Logged in on Device
  4. Guest Login

Authv4Helper is a class that performs a series of processes related to login and is configured to navigate to the appropriate screen based on the response value. Please refer to the following points when configuring the login.

Note

Apple does not support Apple Game Center and in-app purchases in iOS enterprise builds. Therefore, implicit login using an Apple Game Center account cannot be used in iOS enterprise builds, and explicit login cannot use Apple Game Center either. When building for iOS enterprise, the login types in the console must not include Apple Game Center.

Note
Note
  • In China, Google Play games cannot be used, so implicit login cannot be used on Android.
  • In China, Facebook cannot be used, so Facebook is not included in the IdP list.
  • In China, only users with real-name authentication can recharge or consume services (effective from May 1, 2017), so guest login is not included in the IdP list for logins from Chinese IPs.
Note

iOS does not display the login screen even if the Apple Game Center login is canceled. Therefore, the guidance message can either be displayed directly by the SDK calling the AuthV4Helper class's showGameCenterLoginCancelDialog() method or chosen to be displayed by the game. If you want to provide a message for users to reconnect their Game Center account, use the Game Center cancellation guidance message when the callback result of AuthV4.signIn(AuthV4.ProviderType.APPLE, ...) and AuthV4.connect(AuthV4.ProviderType.APPLE, ...) is Cancel.

Note

If a user attempts to log in with Apple when their device is not logged in with an Apple ID, an AuthV4SignInAppleUnknown error occurs during the process of calling the connect(), signIn() methods of the AuthV4Helper class here. The Apple ID login guidance popup is automatically displayed, so the game studio does not need to display a separate guidance popup.

If a user attempts to log in with Apple while their device is not logged in with an Apple ID, an AuthV4SignInAppleUnknown error occurs during the process of calling the AuthV4Helper class's connect(), signIn() methods. The Apple ID login guidance popup is automatically displayed, so the game studio does not need to display a separate popup for guidance.

Note

For PC X IdP login, logging in with an X account is possible, but logging in with Google and Apple account integration on the X login screen is not supported. To log in to X with Google or Apple account integration, you must first log in with the respective account in an external browser and then proceed with X login in the game.
For Steam Deck X IdP login, only logging in with an X account is supported.

Automatic login and implicit login

Automatic login

This refers to the method of logging in where the user does not select a login method, and on iOS, it automatically links to the Apple Game Center account, while on Android, it links to the Google Play Games account. It implements automatic login and performs implicit login in case of failure of automatic login.

To use automatic login in the iOS environment, you need to add the Game Center Entitlement, which Unity automatically adds through Unity PostProcess if you checked the 'Apple GameCenter' Dependency. In iOS Native, Xcode automatically adds the Game Center Entitlement.

Offline mode

In Hive SDK v4 23.1.0 and above, the automatic login feature (AuthV4.signIn using ProviderType.AUTO, or AuthV4.Helper.signIn) can be provided even if the user device is not connected to the network when the app is launched. To use offline mode, please follow the instructions below.

  1. You must have successfully executed the app online for explicit, implicit, guest, or custom login, and received playerId and playerToken.

From the perspective of the app developer, it is necessary to have successfully executed AuthV4.Helper.signIn, AuthV4.showSignIn, or AuthV4.signInWithAuthKey at least once while online to receive playerId and playerToken via callback. From the user's perspective, the user must have successfully logged into the app at least once while their device is connected to the network. However, if the user's account was suspended or restricted at the time of their last login attempt while online, the user will not be able to log in even in offline mode.

  1. Activate offline mode in the Hive console App Center > Project Management > Game Details > Hive Product Settings.

Automatic login in Windows environment

The Windows environment also supports automatic login, which can be enabled/disabled in the Hive Console App Center. However, automatic login in Windows behaves differently than on mobile. The following are the differences for automatic login in Windows.

  • On mobile, after logging in, the login state is always maintained through automatic login, but on Windows, it is only maintained if the user activates the "Keep me logged in" checkbox (displayed at the bottom of the IdP list in the login UI). In other situations, the login state is not maintained.
  • When executing AuthV4Helper.Connect, on mobile, if switching to a new account, the new account will also maintain the automatic login state, but on Windows, if switching to a new account, the new account will not maintain the automatic login state.

Implicit login

  • Implicit Login Flow

AuthV4.Helper.signIn attempts to automatically log in using the authentication token key of the PlayerID. If there is no existing authentication token key, it automatically logs in to Apple Game Center for iOS and Google Play Games for Android. If the login fails, it configures the appropriate login screen based on the response value.

Note

To use automatic login, you must add the Game Center Entitlement. If you checked the 'Apple GameCenter' Dependency, it will automatically add the corresponding Entitlement through Unity PostProcess.

Note

When using the AuthV4Helper class

If a user who has launched the game rejects the implicit login attempt during PGS, it will remember this and will no longer attempt implicit login. Even if automatic login is possible while the player session is maintained, it will continue to remember the state of the rejected implicit login. This content is based on the Google Play Games Services guide.

The following is an example code that performs automatic login.

API Reference: hive.AuthV4.Helper.signIn

// Attempt to sign in (signIn) with Hive SDK
AuthV4.Helper.signIn (delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) {

    if (result.isSuccess()) {
        // Login successful
    } else if (result.needExit()) {
        // TODO: Implement app exit functionality
        // e.g. Application.Quit();
    } else {
        switch (result.code) {
            case ResultAPI.Code.AuthV4ConflictPlayer:
                // Account conflict
                break;
            case ResultAPI.Code.AuthV4HelperImplifiedLoginFail:
                // Failed implicit login
                // ex) AuthV4.showSignIn(...);
                break;
            default:
  k              // Other exceptions
                break;
        }
    }
});
#include "HiveAuthV4.h"

// Attempt to log in (signIn) to Hive SDK
FHiveAuthV4::Helper::SignIn(FHiveAuthV4HelperDelegate::CreateLambda([this](const FHiveResultAPI& Result, const TOptional<FHivePlayerInfo>& PlayerInfo) {
    if (Result.IsSuccess()) {
        // Login successful
    } else if (Result.NeedExit()) {
        // TODO: Implement app exit functionality
        // e.g.) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
    } else {
        switch (Result.Code) {
            case FHiveResultAPI::ECode::AuthV4ConflictPlayer:
                // Account conflict
                break;
            case FHiveResultAPI::ECode::AuthV4HelperImplifiedLoginFail:
                // Failed implicit login
                // ex) FHiveAuthV4::ShowSigIn()
                break;
            default:
                // Other exceptions
                break;
        }
    }
}));

API Reference: Auth4::Helper::signIn

// Attempt to sign in (signIn) with Hive SDK
AuthV4::Helper::signIn([=](ResultAPI const & result, std::shared_ptr playerInfo) {

    if (result.isSuccess()) {
        // Login successful
    } else if (result.needExit()) {
        // TODO: Implement app exit functionality
        // For Cocos2d-x engine users
        // e.g. exit(0);
        // For Unreal engine users
        // e.g. UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
    } else {
        switch (result.code) {
            case ResultAPI::AuthV4ConflictPlayer:
                // Account conflict
                break;
            case ResultAPI::AuthV4HelperImplifiedLoginFail:
                // Implicit login failed
                // ex) AuthV4.showSignIn(...);
                break;
            default:
                break;
        }
    }
});

API Reference: hive.AuthV4.Helper.signIn

// Attempt to sign in using Hive SDK
AuthV4.Helper.signIn(object : AuthV4.Helper.AuthV4HelperListener {
    override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
            // Sign in successful
        } else if (result.needExit()) {
            // TODO: Implement app exit functionality
            // e.g.) exitProcess(0)
        } else {
            when (result.code) {
                ResultAPI.Code.AuthV4ConflictPlayer -> {
                    // Account conflict
                }
                ResultAPI.Code.AuthV4HelperImplifiedLoginFail -> {
                    // Failed implicit login
                    // e.g.) AuthV4.showSignIn(...)
                }
                else -> {
                    // Other exception situations
                }
            }
        }
    }
})

API Reference: com.hive.AuthV4.Helper.signIn

// Hive SDK AuthV4 authentication UI request
AuthV4.Helper.signIn(new AuthV4.Helper.AuthV4HelperListener() {
    @Override
    public void onAuthV4Helper(ResultAPI result, PlayerInfo playerInfo) {

        if (result.isSuccess()) {
            // Authentication successful
        } else if (result.needExit()) {
            // TODO: Implement app exit functionality
            // e.g.) System.exit(0);
        } else {
            switch (result.code) {
                case ResultAPI.Code.AuthV4ConflictPlayer:
                    // Account conflict
                    break;
                case ResultAPI.Code.AuthV4HelperImplifiedLoginFail:
                    // Failed implicit login
                    // ex) AuthV4.showSignIn(...);
                    break;
                default:
                    // Other exceptional situations
                    break;    
            }
        }
    }
});

API Reference: HIVEAuthV4Helper:signIn

// Hive SDK AuthV4 authentication UI request
AuthV4Interface.helper().signIn { (result, playerInfo) in

    if result.isSuccess() {
        // Authentication successful
    } else if result.needExit() {
        // TODO: Implement app exit functionality
        // e.g.) exit(0)
    } else {
        switch result.getCode() {
            case .authV4ConflictPlayer:
                // Account conflict
                break
            case .authV4HelperImplifiedLoginFail:
                // Failed implicit login
                // ex) AuthV4.showSignIn(...)
                break
            default:
                // Other exception situations
                break
            }
        }
    }
}

API Reference: HIVEAuthV4:signIn

// Attempt to sign in (signIn) to Hive SDK    
[[HIVEAuthV4 helper] signIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {

    if (result.isSuccess) {
        // Login successful 
    }
    else if (result.needExit) {
        // TODO: Implement app exit functionality
        // ex) exit(0);
    }
    else {
        switch (result.code) {
            case kAuthV4ConflictPlayer:
                // Account conflict
                break;    
            case kAuthV4HelperImplifiedLoginFail:
                // Implicit login failed
                // ex) [HIVEAuthV4 showSignIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
                // // do something...
                // }];
                break;
            default:
                // Other exceptions
                break;   
        }
    }
}];

Implicit login behavior: Mobile

Implicit login on mobile (Hive SDK Unity Android, etc. Android/iOS platforms) (AuthV4.Helper.signIn) will prompt the user with a dialog asking whether to log in with the last logged-in account in case of an account conflict when logging in with a different account after the first login.

Implicit login behavior: PC

Implicit login on PC (Windows platforms such as Hive SDK Unity Windows) (AuthV4.Helper.signIn) automatically logs in with the last logged-in account when logging in with a different account after the initial login. There will be no account conflict situations.

Explicit login

Explicit login refers to the process where a user selects the IdP to authenticate. If both automatic login and implicit login fail, implement it so that explicit login is performed when the user clicks on the title after moving to the game title screen.

The explicit login UI can either use the UI provided by the Hive SDK or be customized using the list of IdPs returned as a result after the Hive SDK initialization is complete. If you are customizing the UI, please refer to the Explicit Login Customizing section.

The IdP list is controlled and provided by the Hive platform according to the policies of each country. For example, in China, Google Play games and Facebook are not available for guests.

Explicit login screenshot

IdP Selection UI Provided by SDK

When implementing using the UI provided by the SDK

To implement explicit login using the UI provided by the SDK, you can simply call the showSignIn() method to invoke the IdP list UI.

Note

User must be provided a means to log in again if they close the 'X' button in the IdP selection UI provided by the SDK. The user is still not logged in.

Note

To customize explicit sign-in, please refer to the following.

API Reference: hive.AuthV4.showSignIn

// Hive SDK AuthV4 authentication UI request
AuthV4.showSignIn((ResultAPI result, AuthV4.PlayerInfo playerInfo)=>{
    if (result.isSuccess()) {
        // Authentication successful
        // playerInfo : Authenticated user information

        // Example of retrieving email information
        foreach (KeyValuePair<AuthV4.ProviderType, AuthV4.ProviderInfo> entry in playerInfo.providerInfoData) {

            AuthV4.ProviderInfo providerInfo = entry.Value;
            if(providerInfo.providerEmail != null && providerInfo.providerEmail != "") {
                string email = providerInfo.providerEmail;
                break;
            }
        }
    }
    else if (result.needExit()) {
        // TODO: Implement the app exit functionality
        // e.g.) Application.Quit();
    }
});
#include "HiveAuthV4.h"

// Hive SDK AuthV4 authentication UI request
FHiveAuthV4::ShowSignIn(FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {
    if (Result.IsSuccess()) {
        // Authentication successful (PlayerInfo: authenticated user information) 

        // Example of retrieving email information
        for (const auto& ProviderInfoEntry : PlayerInfo.ProviderInfoData) {
            FHiveProviderInfo ProviderInfo = ProviderInfoEntry.Value;
            FString Email = ProviderInfo.ProviderEmail;
        }
    } else if (Result.NeedExit()) {
        // TODO: Implement app exit functionality
        // Example) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
    }
}));

API Reference: AuthV4::showSignIn

// Hive SDK AuthV4 authentication UI request
AuthV4::showSignIn([=](ResultAPI const & result, PlayerInfo const & playerInfo) {
    if (result.isSuccess()) {
        // Authentication successful
        // playerInfo: authenticated user information

        // Example of retrieving email information
        for(auto it = playerInfo.providerInfoData.begin(); it != playerInfo.providerInfoData.end(); ++it) {
            hive::ProviderInfo providerInfo = it->second;
            if(!providerInfo.providerEmail.empty()) {
                std::string email = providerInfo.providerEmail;
                break;
            }
        }
    }
    else if (result.needExit()) {
        // TODO: Implement app exit functionality
        // Cocos2d-x engine users
        // Example) exit(0);
        // Unreal engine users
        // Example) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
    }
});

API Reference: com.hive.AuthV4.showSignIn

// Hive SDK AuthV4 authentication UI request
AuthV4.showSignIn(object : AuthV4.AuthV4SignInListener {
    override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
            // Authentication successful
            // playerInfo: Authenticated user information

            // Example of retrieving email information
            playerInfo?.let {
                for ((key, value) in it.providerInfoData) {
                    var providerInfo: AuthV4.ProviderInfo = value
                    if(providerInfo.providerEmail.isNotEmpty()) {
                        val email = providerInfo.providerEmail
                        break
                    }
                }
            }
        } else if (result.needExit()) {
            // TODO: Implement app exit functionality
            // e.g.) exitProcess(0)
        }
    }
})

API Reference: com.hive.AuthV4.showSignIn

// Hive SDK AuthV4 authentication UI request
AuthV4.showSignIn(new AuthV4.AuthV4SignInListener() {
    @Override
    public void onAuthV4SignIn(ResultAPI result, AuthV4.PlayerInfo playerInfo) {

        if (result.isSuccess()) {
            // Authentication success
            // playerInfo: Authenticated user information

            // Example of retrieving email information
            if(playerInfo != null) {
                for (Map.Entry<AuthV4.ProviderType, AuthV4.ProviderInfo> entry : playerInfo.getProviderInfoData().entrySet()) {
                    AuthV4.ProviderInfo providerInfo = entry.getValue();
                    if (providerInfo.getProviderEmail() != "") {
                        String email = providerInfo.getProviderEmail();
                        break;
                    }
                }
            }
        }
        else if (result.needExit()) {
            // TODO: Implement app exit functionality
            // e.g. System.exit(0);
        }
    }
});

API Reference: HIVEAuthV4:showSignIn

var email = String()

// Hive SDK AuthV4 authentication UI request
AuthV4Interface.showSignIn { (result, playerInfo) in

    if result.isSuccess() {
        // Authentication successful
        // playerInfo: Authenticated user information

        // Example of retrieving email information
        if let playerInfo = playerInfo {
            // Searching for providerInfo where providerEmail exists (currently logged-in provider)
            for key in playerInfo.providerInfoData.keys {
                if let providerInfo = playerInfo.providerInfoData[key],
                    providerInfo.providerEmail.count > 0 {
                    // providerEmail != ""
                    email = providerInfo.providerEmail
                    break
                }
            }
        }
    } else if result.needExit() {
        // TODO: Implement app exit functionality
        // e.g. exit(0)
    }
}

API Reference: HIVEAuthV4:showSignIn

__block NSString* email = @"";

// Hive SDK AuthV4 authentication UI request
[HIVEAuthV4 showSignIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {

    if([result isSuccess]){
        // Authentication successful
        // playerInfo: Authenticated user information

        // Example of retrieving email information
        if(playerInfo != nil) {
            // Search for providerInfo with existing providerEmail (currently logged in provider)
            for (NSString* key in playerInfo.providerInfoData.allKeys) {
                HIVEProviderInfo* providerInfo = playerInfo.providerInfoData[key];
                if (providerInfo != nil && providerInfo.providerEmail.length > 0) {
                    // providerEmail != ""
                    email = providerInfo.providerEmail;
                    break;
                }
            }
        }
    } else if ([result needExit]) {
        // TODO: Implement app exit functionality
        // e.g. exit(0);
    }
}];

Explicit login customization

The customizable UI for explicit login can be implemented using providerTypeList. The providerTypeList is the response callback handler returned when calling the AuthV4.setup() method for initializing the Hive SDK, or when calling the AuthV4.Helper.getIDPList() method after initialization. This feature is used when you want to display the login screen according to the game UI or primarily expose integration with specific IdPs. After implementing the customizable UI, call the signIn() method with the desired ProviderType based on the user's action to implement the login.

Note
  • UI example screenshot showing only the Facebook integration button on the login screen

The following is an example source code assuming a situation where the user selects Google login in a customized explicit login UI.

API Reference: hive.AuthV4.signIn

using hive;

AuthV4.signIn(AuthV4.ProviderType.GOOGLE, (ResultAPI result, AuthV4.PlayerInfo playerInfo) => {
    if (result.isSuccess()) {
        // Call succeeded
        // playerInfo : authenticated user information.
        // Example of retrieving email information for ProviderType.GOOGLE
        Dictionary<AuthV4.ProviderType, AuthV4.ProviderInfo> providerInfoData = playerInfo.providerInfoData;
        AuthV4.ProviderInfo providerInfo = providerInfoData[AuthV4.ProviderType.GOOGLE];
        string email = providerInfo.providerEmail;
    }
});
#include "HiveAuthV4.h"

FHiveAuthV4::SignIn(EHiveProviderType::GOOGLE,
                    FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {

    if (Result.IsSuccess()) {
        // Call succeeded (PlayerInfo: authenticated user information) 

        // Example of retrieving email information for EHiveProviderType::GOOGLE
        TMap<EHiveProviderType, FHiveProviderInfo> ProviderInfoData = PlayerInfo.ProviderInfoData;
        if (const FHiveProviderInfo* ProviderInfo = ProviderInfoData.Find(EHiveProviderType::GOOGLE)) {
                FString Email = ProviderInfo->ProviderEmail;
        }
    }
}));

API Reference: Auth4::signIn

#include <HIVE_SDK_Plugin/HIVE_CPP.h>

AuthV4::signIn(ProviderType::GOOGLE, [=](ResultAPI const & result, PlayerInfo const & playerInfo) {
    if (result.isSuccess()) {
        // Call successful
        // playerInfo : Authenticated user information.

        // Example of retrieving email information for ProviderType::GOOGLE
        map<ProviderType, ProviderInfo> providerInfoData = playerInfo.providerInfoData;
        ProviderInfo providerInfo = providerInfoData[ProviderType::GOOGLE];
        string email = providerInfo.providerEmail;
    }
});

API Reference: AuthV4.signIn

import com.hive.AuthV4
import com.hive.ResultAPI

AuthV4.signIn(AuthV4.ProviderType.GOOGLE, object : AuthV4.AuthV4SignInListener {
    override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
            // Call succeeded
            // playerInfo: authenticated user information
            // Example of retrieving email information for ProviderType.GOOGLE
            if (playerInfo != null) {
                val providerInfoData = playerInfo.providerInfoData
                val providerInfo = providerInfoData[AuthV4.ProviderType.GOOGLE]
                if (providerInfo != null) {
                    val email = providerInfo.providerEmail
                }
            }
        }
    }
})

API Reference: com.hive.Auth4.signIn

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.signIn(AuthV4.ProviderType.GOOGLE, (result, playerInfo) -> {
    if (result.isSuccess()) {
        // Call successful
        // playerInfo: authenticated user information
        // Example of retrieving email information for ProviderType.GOOGLE
        if (playerInfo != null) {
            HashMap<AuthV4.ProviderType, AuthV4.ProviderInfo> providerInfoData = playerInfo.getProviderInfoData();
            AuthV4.ProviderInfo providerInfo = providerInfoData.get(AuthV4.ProviderType.GOOGLE);
            if (providerInfo != null) {
                String email = providerInfo.getProviderEmail();
            }
        }
    }
});

API Reference: AuthV4Interface.signIn

import HIVEService

AuthV4Interface.signIn(.Google) { result, playerInfo in    
    if result.isSuccess() {
        // Call successful
        // playerInfo: Authenticated user information.

        // Example of retrieving Google's email information
        if 
            let playerInfo = playerInfo,  
            let providerInfo = playerInfo.providerInfoData["GOOGLE"] {
                let email = providerInfo.providerEmail
        }
    }
}

API Reference: HIVEAuth4:signIn

#import <HIVEService/HIVEService-Swift.h>

[HIVEAuthV4 signIn:HIVEProviderTypeGoogle handler:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
    if ([result isSuccess]){
        // Call succeeded
        // playerInfo: Authenticated user information.

        // Example of retrieving email information for HIVEProviderTypeGoogle
        if(playerInfo != nil) {
            HIVEProviderInfo *providerInfo = playerInfo.providerInfoData[@"GOOGLE"];
            if(providerInfo != nil){
                NSString *email = providerInfo.providerEmail;
            }
        }
    }
}];

Check IdP account logged in on device

Automatic login uses the authentication token key of the saved PlayerID to log in, while explicit login logs into accounts linked to multiple IdPs. In both cases, the IdP account of the logged-in PlayerID may differ from the IdP account logged into the actual device (DevicePlayer). Guidance will be provided to unify the two accounts in preparation for future achievements or leaderboard usage.

  • Check UI for DevicePlayer provided by SDK

The following is an example code to check IdP information.

API Reference: AuthV4.Helper.syncAccount

using hive;

AuthV4.ProviderType providerType = AuthV4.ProviderType.GOOGLE;
AuthV4.Helper.syncAccount (providerType, delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) {

    switch (result.code) {
        case ResultAPI.Code.Success:
            // Normal
            break;   
        case ResultAPI.Code.AuthV4ConflictPlayer:
            // Account conflict
            // ex) When using Hive UI
            // AuthV4.Helper.showConflict(...);
            // or
            // ex) When implementing GameUI
            // AuthV4.Helper.resolverConflict(...);// When selecting current user
            // AuthV4.Helper.switchAccount(...);// When selecting user switch 
            break;
        default:  
            // Other exceptions
            break;
    }
});
#include "HiveAuthV4.h"

FHiveAuthV4::Helper::SyncAccount(ProviderType, 
                                 FHiveAuthV4HelperDelegate::CreateLambda([this](const FHiveResultAPI& Result, 
                                                                                const TOptional<FHivePlayerInfo>& PlayerInfo) {

    switch (Result.Code) {
        case FHiveResultAPI::ECode::Success:
            // Normal response
            break;
        case FHiveResultAPI::ECode::AuthV4ConflictPlayer:
            // Account conflict
            // ex) When using Hive UI
            // FHiveAuthV4::Helper::ShowConflict()
            // ex) When implementing Game UI
            // FHiveAuthV4::Helper::ResolveConflict() // Current user selection
            // FHiveAuthV4::Helper::SwitchAccount() // User switch selection
            break;
        default:
            // Other exceptional situations
            break;
    }
}));

API Reference: AuthV4::Helper::syncAccount

#include <HIVE_SDK_Plugin/HIVE_CPP.h>
using namespace std;
using namespace hive;

ProviderType providerType = ProviderType::GOOGLE;
AuthV4::Helper::syncAccount(providerType, [=](ResultAPI const & result, shared_ptr<PlayerInfo> playerInfo) {

    switch (result.code) {
        case ResultAPI::Success:
            // Normal
            break;   
        case ResultAPI::AuthV4ConflictPlayer:
            // Account conflict
            // ex) When using Hive UI
            // AuthV4::Helper::showConflict(...);
            // or
            // ex) When implementing GameUI
            // AuthV4::Helper::resolverConflict(...);// When selecting current user
            // AuthV4::Helper::switchAccount(...);// When selecting to switch user 
            break;
        default:  
            // Other exception situations
            break;
    }
});

API Reference: AuthV4.Helper.syncAccount

import com.hive.AuthV4
import com.hive.ResultAPI

val providerType = AuthV4.ProviderType.GOOGLE
AuthV4.Helper.syncAccount(providerType, object : AuthV4.Helper.AuthV4HelperListener {
    override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {    
        when (result.code) {
            ResultAPI.Code.Success -> {
                // Normal
            }
            ResultAPI.Code.AuthV4ConflictPlayer -> {
                // Account conflict
                // ex) When using Hive UI
                // AuthV4.Helper.showConflict(...);
                // or
                // ex) When implementing GameUI
                // AuthV4.Helper.resolverConflict(...);// When selecting current user
                // AuthV4.Helper.switchAccount(...);// When selecting user switch 
            }
            else -> {
                // Other exceptional situations
            }
        }
    }
})

API Reference: AuthV4.Helper.syncAccount

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.ProviderType providerType = AuthV4.ProviderType.GOOGLE;
AuthV4.Helper.syncAccount(providerType, (result, playerInfo) -> {
    switch (result.getCode()) {
        case Success:
            // Normal  
        case AuthV4ConflictPlayer:    
            break;   
            // Account conflict
            // ex) When using Hive UI
            // AuthV4.Helper.showConflict(...);
            // or
            // ex) When implementing GameUI
            // AuthV4.Helper.resolverConflict(...);// When selecting current user
            // AuthV4.Helper.switchAccount(...);// When selecting user switch 
            break;
        default:  
            // Other exceptions
            break;
    }
});

API Reference: AuthV4Interface.helper().syncAccount

import HIVEService
let providerType: ProviderType = .Google

AuthV4Interface.helper().syncAccount(providerType) { result, playerInfo in
    switch result.getCode() {
        case .success:
        // Normal
        case .authV4ConflictPlayer:
        // Account conflict
        // ex) When using Hive UI
        // AuthV4Interface.helper().showConflict(...);
        // or
        // ex) When implementing GameUI
        // AuthV4Interface.helper().resolverConflict(...);// When the current user is selected
        // AuthV4Interface.helper().switchAccount(...);// When the user switch is selected 
        default:
        // Other exceptional situations
        break
    }
}

API Reference: [HIVEAuthV4 helper] syncAccount

#import <HIVEService/HIVEService-Swift.h>

HIVEProviderType providerType = HIVEProviderTypeGoogle
[[HIVEAuthV4 helper] syncAccount: providerType handler: ^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
    switch ([result getCode]) {
        case HIVEResultAPICodeSuccess:
            // Normal
            break;    
        case HIVEResultAPICodeAuthV4ConflictPlayer:
            // Account conflict
            // ex) When using Hive UI
            // [[HIVEAuthV4 helper] showConflict: ...];
            // or
            // ex) When implementing GameUI
            // [[HIVEAuthV4 helper] resolverConflict:...];// When current user is selected
            // [[HIVEAuthV4 helper] switchAccount:...];// When user switch is selected  
            break;
        default:  
            // Other exceptions
            break;
    }
}];

Guest login

The guest login feature allows users to play the game in guest mode without selecting an IdP. You can select guest login from the explicit login UI provided by the Hive SDK, or implement guest login directly if you are customizing it in your game. The Windows environment does not support guest login.

When logging in as a guest, you must adhere to the following policies.

Guest login policy

  • Implement the game so that both IdP authenticated users and guest users can use it in the same way. Most features of the Hive platform can be used even when logging in as a guest. Therefore, please implement your game so that users logged in as guests can use the game in the same way as IdP linked users. For example, guest users should also be able to purchase items and make payments within the game.
    • Do not provide a logout function for guest users. If a user logs out after logging in as a guest, they will no longer be able to log in with the same PlayerID. Therefore, do not provide a logout button so that users cannot log out when they are logged in as guests.
    • China guest login prohibition policy If using a Chinese IP, only users who have undergone real-name verification can recharge and consume resources (effective from May 1, 2017), so guest logins are not included in the list of IdPs that can log in with a Chinese IP.

To perform guest login, call the signIn() method with ProviderType.GUEST as a parameter. Here is an example code for performing guest login.

Note

There is no providerInfoData in playerInfo for PlayerID in guest state without any IdP authentication.

API Reference: hive.AuthV4.signIn

using hive;

AuthV4.signIn(AuthV4.ProviderType.GUEST, (ResultAPI result, AuthV4.PlayerInfo playerInfo) => {
    if (result.isSuccess()) {
        // Authentication successful
        // playerInfo: Authenticated user information
    }
});
#include "HiveAuthV4.h"

FHiveAuthV4::SignIn(EHiveProviderType::GUEST, 
                    FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {

    if (Result.IsSuccess()) {
            // Call succeeded (PlayerInfo: Authenticated user information)
    }
}));

API Reference: Auth4::signIn

#include <HIVE_SDK_Plugin/HIVE_CPP.h>

using namespace std;
using namespace hive;
AuthV4::signIn(ProviderType::GUEST, [=](ResultAPI const & result, PlayerInfo const & playerInfo) {
    if (result.isSuccess()) {
        // Authentication successful
        // playerInfo: Authenticated user information
    }
});

API Reference: AuthV4.signIn

import com.hive.AuthV4
import com.hive.ResultAPI

AuthV4.signIn(AuthV4.ProviderType.GUEST, object : AuthV4.AuthV4SignInListener {
    override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
            // Authentication successful
            // playerInfo: Authenticated user information
        }
    }
})

API Reference: com.hive.Auth4.signIn

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.signIn(AuthV4.ProviderType.GUEST, (result, playerInfo) -> {
    if (result.isSuccess()) {
        // Authentication successful
        // playerInfo: Authenticated user information
    }
});

API Reference: AuthV4Interface.signIn

import HIVEService

AuthV4Interface.signIn(.Guest) { result, playerInfo in
    if result.isSuccess() {
        // Authentication successful
        // playerInfo: Authenticated user information
    }
}

API Reference: HIVEAuth4:signIn

#import <HIVEService/HIVEService-Swift.h>

[HIVEAuthV4 signIn: HIVEProviderTypeGuest handler: ^(ResultAPI *result, HIVEPlayerInfo *playerInfo) {
    if ([result isSuccess]) {
        // Authentication successful
        // playerInfo: Authenticated user information
    }
}];

Custom login

Custom Login is a feature for customized login, allowing you to implement login through an IdP integrated with the game itself, in addition to the IdP provided by Hive. Try generating an authentication key (authKey) to use when calling the custom login API according to Authenticate v4 Custom Authentication.

After calling the custom login API, you can access the customProviderInfoData data through the PlayerInfo class instance received as a callback to check the information of the custom logged-in user. The ProviderType (enum) of customProviderInfoData is set uniformly to CUSTOM, and it can be distinguished in detail by ProviderName (String).

The information of the IdP that implemented custom login in the game is not included in the results of the setup() and showSignIn() method calls of the AuthV4 class.

If you have received a playerId and playerToken after the first execution of the custom login, the Result API of authV4SessionExist(code) will be delivered as a callback when the custom login API is recalled. In this case, you should call signIn() with ProviderType.Auto as a parameter to proceed with the automatic login using the already logged-in account. Please refer to the example code below.

The connect() and disconnect() methods of the AuthV4 class do not support additional integration and disconnection of the custom login IdP. The connectWithAuthKey() and disconnectWithName() methods support additional integration and disconnection of the custom login IdP.

This is an example code for implementing custom login.

API Reference: hive.AuthV4.signIn

// Twitter login implemented directly in the game
Game.Login("CUSTOM_TWITTER", (string authKey) => {
    AuthV4.signInWithAuthKey(authKey, (ResultAPI result, PlayerInfo playerInfo) => {
        if (result.isSuccess()) {
            Dictionary<string, ProviderInfo> customProviderInfoData = playerInfo.customProviderInfoData;
            ProviderInfo providerInfo = customProviderInfoData["CUSTOM_TWITTER"];
            // Check the following user linkage information
            providerInfo.providerType;     // ProviderType.CUSTOM, custom types are fixed, so need to distinguish by providerName
            providerInfo.providerName;   // "CUSTOM_TWITTER"
            providerInfo.providerUserId;  // User id used for the custom Twitter login
            return;
        }
        else if (result.code == ResultAPI.Code.AuthV4SessionExist) {
            // If playerId and playerToken have already been issued and automatic login is needed
            // TODO: AuthV4.signIn(ProviderType.AUTO, (ResultAPI _result, PlayerInfo playerInfo) => {});
        }
        else if (result.code == ResultAPI.Code.AuthV4NotInitialized) {
            // TODO: SDK initialization needed
        }
        else if (result.code == ResultAPI.Code.AuthV4InvalidParam) {
            // TODO: Check if the value of the provided authKey is NULL or empty
        }
        else if (result.needExit()) {
            // TODO: Implement app exit functionality
            // Example) Application.Quit();
        }
    });  
});
#include "HiveAuthV4.h"

// Directly implemented Twitter login in the game with "CUSTOM_TWITTER" type
void GameLogin(const FString& AuthKey)
{
    FHiveAuthV4::SignInWithAuthKey(AuthKey, FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {

        if (Result.IsSuccess()) {
            TMap<FString, FHiveProviderInfo> CustomProviderInfoData = PlayerInfo.CustomProviderInfoData;
            if (const FHiveProviderInfo* ProviderInfo = CustomProviderInfoData.Find(TEXT("CUSTOM_TWITTER"))) {
                    EHiveProviderType ProviderType = ProviderInfo->ProviderType; // EHiveProviderType::CUSTOM, custom types are fixed
                    FString ProviderName = ProviderInfo->ProviderName; // Need to distinguish by ProviderName
                    FString ProviderUserId = ProviderInfo->ProviderUserId; // User id used in the custom Twitter login
            }
        } else if (Result.NeedExit()) {
            // TODO: Implement app exit functionality
            // e.g.) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
        } else if (Result.Code == FHiveResultAPI::ECode::AuthV4SessionExist) {
            // If playerId and playerToken have already been issued and automatic login is needed
            // TODO: FHiveAuthV4.SignIn(EHiveProviderType::GUEST, Delegate);
        } else if (Result.Code == FHiveResultAPI::ECode::AuthV4NotInitialized) {
            // TODO: SDK initialization needed
        } else if (Result.Code == FHiveResultAPI::ECode::AuthV4InvalidParam) {
            // TODO: Check if the value of the provided authKey is empty
        }
    }));
}

API Reference: Auth4::signIn

using namespace std;
using namespace hive;

// Twitter login implemented directly in the game
Game::Login("CUSTOM_TWITTER", [=](string authKey) {
    AuthV4::signInWithAuthKey(authKey, [=](ResultAPI const & result, PlayerInfo const & playerInfo) {
        if (result.isSuccess()) {
            map<string, ProviderInfo> customProviderInfoData = playerInfo.customProviderInfoData;
            ProviderInfo providerInfo = customProviderInfoData["CUSTOM_TWITTER"];
            // Check the following user linkage information
            providerInfo.providerType; // ProviderType::CUSTOM, since custom types are fixed, need to distinguish by providerName
            providerInfo.providerName; // "CUSTOM_TWITTER"
            providerInfo.providerUserId; // User id used for the custom Twitter login
            return;
        }
        else if (result.code == ResultAPI::Code::AuthV4SessionExist) {
            // If playerId and playerToken have already been issued and automatic login is needed
            // TODO: AuthV4.signIn(ProviderType::AUTO, [=](ResultAPI const & _result, PlayerInfo const & playerInfo) {});
        }
        else if (result.code == ResultAPI::Code::AuthV4NotInitialized) {
            // TODO: SDK initialization needed
        }
        else if (result.code == ResultAPI::Code::AuthV4InvalidParam) {
            // TODO: Check if the value of the provided authKey is NULL or empty
        }
        else if (result.needExit()) {
            // TODO: Implement app exit functionality
            // For Cocos2d-x engine users
            // Example) exit(0);
            // For Unreal engine users
            // Example) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
        }
    });  
});

API Reference: com.hive.Auth4.signIn

// Twitter login implemented directly in the game
Game.Login("CUSTOM_TWITTER") { authKey: String ->

    AuthV4.signInWithAuthKey(authKey, object : AuthV4.AuthV4SignInListener {
        override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {

            if (result.isSuccess && playerInfo != null) {
                playerInfo.customProviderInfoData["CUSTOM_TWITTER"]?.let { providerInfo ->
                    providerInfo.providerType   // ProviderType.CUSTOM, custom types are fixed, so need to distinguish by providerName
                    providerInfo.providerName   // "CUSTOM_TWITTER"
                    providerInfo.providerUserId // User id used for the custom Twitter login
                }
            }
            else if (result.needExit()) {
                // TODO: Implement app exit functionality
                // e.g.) exitProcess(0)
            }
            else if (result.code == ResultAPI.Code.AuthV4SessionExist) {
                // If playerId and playerToken have already been issued and automatic login is needed
                // TODO: AuthV4.signIn(AuthV4.ProviderType.AUTO, authV4SignInListener)
            }
            else if (result.code == ResultAPI.Code.AuthV4NotInitialized) {
                // TODO: SDK initialization needed
            }
            else if (result.code == ResultAPI.Code.AuthV4InvalidParam) {
                // TODO: Check if the value of the provided authKey is NULL or empty
            }
        }
    })
}

API Reference: com.hive.Auth4.signIn

// Twitter login implemented directly in the game
Game.Login("CUSTOM_TWITTER") { authKey: String ->
    AuthV4.signInWithAuthKey(authKey, new AuthV4.AuthV4SignInListener() {
        @Override
        public void onAuthV4SignIn(@NonNull ResultAPI result, @Nullable AuthV4.PlayerInfo playerInfo) {

            if(result.isSuccess() && playerInfo != null) {
                HashMap<String, AuthV4.ProviderInfo> customProviderInfoData = playerInfo.getCustomProviderInfoData();
                AuthV4.ProviderInfo providerInfo = customProviderInfoData.get("CUSTOM_TWITTER");
                // Check the following user linkage information
                if (providerInfo != null){
                    providerInfo.getProviderType(); // AuthV4.ProviderType.CUSTOM, since custom types are fixed, need to distinguish by providerName
                    providerInfo.getProviderName(); // "CUSTOM_TWITTER"
                    providerInfo.getProviderUserId(); // User id used for the custom Twitter login implemented directly
                }
            } else if (result.needExit()) {
                // TODO: Implement app exit functionality
                // e.g.) System.exit(0);
            } else if (result.getCode() == ResultAPI.Code.AuthV4SessionExist) {
                // If playerId and playerToken have already been issued and automatic login is needed
                // TODO: AuthV4.signIn(AuthV4.ProviderType.AUTO, authV4SignInListener)
            } else if (result.getCode() == ResultAPI.Code.AuthV4NotInitialized) {
                // TODO: SDK initialization needed
            } else if (result.getCode() == ResultAPI.Code.AuthV4InvalidParam) {
                // TODO: Check if the value of the provided authKey is NULL or empty
            }
        }
    });
}

API Reference: HIVEAuth4:signIn

// Twitter login implemented directly in the game
Game.login("CUSTOM_TWITTER") { (authKey) in
    AuthV4Interface.signInWithAuthKey(authKey) { (result, playerInfo) in
        if result.isSuccess() {
            let customProviderInfoData = playerInfo?.customProviderInfoData;
            let providerInfo = customProviderInfoData?["CUSTOM_TWITTER"]
            // Check the following user linkage information
            providerInfo?.providerType;     // AuthProviderType, custom types are fixed so need to distinguish by providerName
            providerInfo?.providerName;     // "CUSTOM_TWITTER"
            providerInfo?.providerUserId;   // User id used for the custom Twitter login
            return
        }
        else if result.getCode() == .authV4SessionExist {
            // If playerId and playerToken have already been issued and automatic login is needed
            // TODO: AuthV4Interface.signIn(.auto) { (result, playerInfo) in }
        }
        else if result.getCode() == .authV4NotInitialized {
            // TODO: SDK initialization needed
        }
        else if result.getCode() == .authV4invalidParam {
            // TODO: Check if the value of the provided authKey is nil or empty
        }
        else if result.needExit() {
            // TODO: Implement app exit functionality.
            // e.g. exit(0)
        }
    }
}

API Reference: HIVEAuth4:signIn

// Twitter login implemented directly in the game
[Game login:@"CUSTOM_TWITTER" handler:^(NSString* authKey) {

    [HIVEAuthV4 signInWithAuthKey:authKey handler:^(HIVEResultAPI* result, HIVEPlayerInfo* playerInfo) {
        if (result.isSuccess) {
            NSDictionary<NSString*, HIVEProviderInfo*>* customProviderInfoData = playerInfo.customProviderInfoData;
            ProviderInfo* providerInfo = [customProviderInfoData objectForKey:@"CUSTOM_TWITTER"];
            // Check the following user linkage information
            providerInfo.providerType;     // HIVEProviderTypeCustom, custom types are fixed, so need to distinguish by providerName
            providerInfo.providerName;   // "CUSTOM_TWITTER"
            providerInfo.providerUserId;  // User id used in the custom Twitter login
            return;
        }
        else if (result.getCode == HIVEResultAPICodeAuthV4SessionExist) {
            // If playerId and playerToken have already been issued and auto-login is needed
            // TODO: [HIVEAuthV4 signIn:HIVEProviderTypeAuto, handler:^(HIVEResultAPI* _result, HIVEPlayerInfo* playerInfo) {}];
        }
        else if (result.getCode == HIVEResultAPICodeAuthV4NotInitialized) {
            // TODO: SDK initialization is required
        }
        else if (result.getCode == HIVEResultAPICodeAuthV4InvalidParam) {
            // TODO: Check if the value of the provided authKey is NULL or empty
        }
        else if (result.needExit) {
            // TODO: Implement app exit functionality.
            // e.g) exit(0);
        }
    }];   
}];

Username

Due to issues such as COPPA in the United States, when accessing and logging in as an IdP from the United States and its territories, users must enter a username to facilitate additional user identification authentication processing. For reference, the countries included in U.S. territories are American Samoa (AS), Guam (GU), Northern Mariana Islands (MP), Puerto Rico (PR), U.S. Minor Outlying Islands (UM), and U.S. Virgin Islands (VI). The screen for entering the username for user identification is as follows.

  • The username input screen is used only for user identification purposes, so it is displayed only once during the initial IdP integration and will not be shown afterwards.
  • The username input screen is not displayed during guest login.

Verification of authentication token key

The game server can validate the authenticity of the token key using the Token, playerId, and DID information returned after a successful login. Hive authentication allows multi-device logins and concurrent access.

If duplicate access is not allowed with the same account, the game server will display a notification message on the device that connected first and then exit the game, allowing the game to continue on the device that connected later. If you attempt to access the game again without exiting, your gameplay records may not be reflected correctly. To implement this feature, you need to manage a validated token key or the session key of the game itself using it.

Implement this feature by referring to the Authentication Token Key Validation Server API.

Detecting IdP account changes in the background

Users can navigate to device settings during gameplay to change their Apple Game Center or Google Play Games accounts. If you need to check whether the IdP account during gameplay differs from the current PlayerID's IdP account, call setProviderChangedListener() after initializing the SDK. By calling this API, you can receive an event indicating that the IdP account set on the device has changed when the game resumes.

iOS works with Apple Game Center, and Android works with Google Play games when the account is changed, and responses are delivered only if the currently logged-in PlayerID is linked to the corresponding IdP. When receiving an IdP account change event, the UI is configured to allow the user to choose whether to use the IdP account logged into the device. If the user selects the IdP account logged into the device, signOut is called to log out, and then implicit login is performed.

Warning

Devices that installed Google Play games released after July 2021 cannot change IdP accounts in the background due to operational issues with Google Play games.

Note

This feature may cause gameplay to pause and request a change of account, and it can only be used restrictively at times when account synchronization is needed, such as entering the lobby or the shop.

The following is an example code that sets up to receive an event when the user restarts the game and the IdP account set on the device has changed.

API Reference: hive.AuthV4.setProviderChangedListener

using hive;

AuthV4.setProviderChangedListener((ResultAPI result, AuthV4.ProviderInfo providerInfo) => {
    if (!result.isSuccess()) {
        return;
    }

    if (providerInfo != null && providerInfo.providerType == AuthV4.ProviderType.APPLE) {
        // Change GameCenter user information
    }
});
#include "HiveAuthV4.h"

FHiveAuthV4::SetProviderChangedListener(FHiveAuthV4OnCheckProviderDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHiveProviderInfo& ProviderInfo) {
    if (Result.IsSuccess()) {
            // Call succeeded. Check the changed user information through the ProviderInfo object
    }
}));

API Reference: AuthV4::setProviderChangedListener

#include <HIVE_SDK_Plugin/HIVE_CPP.h>
using namespace std;
using namespace hive;

AuthV4::setProviderChangedListener([=](ResultAPI const & result, ProviderInfo const & providerInfo) {
    if (!result.isSuccess()) {
        return;
    }

    if (providerInfo != null && providerInfo.providerType == ProviderType::GOOGLE) {
        // Change Google Play Game Service account
    }
});

API Reference: AuthV4.setProviderChangedListener

import com.hive.AuthV4
import com.hive.ResultAPI

AuthV4.setProviderChangedListener(object : AuthV4.AuthV4CheckProviderListener {
    override fun onDeviceProviderInfo(result: ResultAPI, providerInfo: AuthV4.ProviderInfo?) {
        if (!result.isSuccess) {
            return
        }

        if (providerInfo != null && providerInfo.providerType == AuthV4.ProviderType.GOOGLE) {
            // Change Google Play Game Service account
        }
    }
})

API Reference: com.hive.AuthV4.setProviderChangedListener

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.setProviderChangedListener((result, providerInfo) -> {
    if (!result.isSuccess()) {
        return;
    }

    if (providerInfo != null && providerInfo.getProviderType() == AuthV4.ProviderType.GOOGLE) {
        // Change Google Play Game Service account
    }
});

API Reference: AuthV4Interface.setProviderChangedListener

import HIVEService

AuthV4Interface.setProviderChangedListener() { result, providerInfo in 
    if !result.isSuccess() {
        return
    }

    if let providerInfo = providerInfo, providerInfo.providerType == .Apple {
        // Change GameCenter user information
    }
}

API Reference: HIVEAuthV4:setProviderChangedListener

#import <HIVEService/HIVEService-Swift.h> 

[HIVEAuthV4 setProviderChangedListener: ^(HIVEResultAPI *result, ProviderInfo *providerInfo) {
    if (![result isSuccess]) {
        return;
    }

    if (providerInfo != nil && providerInfo.providerType == HIVEProviderTypeApple) {
        // GameCenter user information change
    }
}];

Game data initialization

Do not call logout when initializing game data. Since the PlayerID is not deleted, conflicts between accounts may occur. You should implement it so that the user can continue playing with the currently logged-in account and do not call logout until the user explicitly requests it.

Logout

Warning
  • During the logout operation, the authentication information PlayerId and session information PlayerToken, as well as the session information of all IDPs, will be deleted.
  • Values set by all APIs starting with set will not be initialized or deleted.
    • All methods starting with set in the Configuration, Auth, Auth v4, Promotion, and Push classes
    • The following are representative examples. ex> Configuration.setServer, Configuration.setUseLog, Configuration.setGameLanguage, Configuration.setHiveCertificationKey, Auth.setEmergencyMode, AuthV4.setProviderChangedListener, Promotion.setUserEngagementReady, Promotion.setAddtionalInfo, Push.setRemotePush, Push.setForegroundPush, etc. All methods starting with set fall under this category.
    • Starting from Hive SDK v4 24.3.0, an error code is returned when a guest user logs out. After that, the client and server sessions are maintained.
  • The validity range of values set through methods starting with set in the SDK is maintained within the app's lifecycle, regardless of login or logout status.

If you have logged in to Hive, the PlayerID and authentication token key have been issued. Logging out performs the function of initializing the PlayerID and authentication token key. When you call the signOut() method to complete the logout, you will be redirected to the game title, and explicit login will be performed when you click on the title.

Note
  • When logging out in guest login status, the same PlayerID can no longer be found, so please implement it so that logout is not provided in guest status.
  • The IdP linkage status of the PlayerID does not change even after logging out.
  • Once the logout is complete, it will move to the game title, and explicit login will be performed when clicking on the title.
  • After logging out, if the app is restarted, implicit login will be performed first.

Here is an example code that performs logout.

API Reference: hive.AuthV4.signOut

using hive;    

AuthV4.Helper.signOut (delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) {    
    switch(result.code) {    
        case ResultAPI.Code.Success:    
            // Logout successful    
            break;    
        default:    
            // Other exceptions    
            break;    
    }    
});
#include "HiveAuthV4.h"

FHiveAuthV4::Helper::SignOut(FHiveAuthV4HelperDelegate::CreateLambda([this](const FHiveResultAPI& Result, const TOptional<FHivePlayerInfo>& PlayerInfo) {
    AHIVESDKV4TesterGameMode::getGameModeInstance()->appendLogString(ELogType::AuthV4Helper ,TEXT("Helper::SignOut Result = %s"), *(Result.ToString()));
    switch (Result.Code) {
        case FHiveResultAPI::ECode::Success:
            // Logout successful
            break;
        default:
            // Other exceptions
            break;
    }
}));

API Reference: AuthV4::signOut

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
using namespace std;    
using namespace hive;    

AuthV4::Helper::signOut([=](ResultAPI const & result, shared_ptr playerInfo) {    
    switch (result.code) {    
        case ResultAPI::Success:    
            // Logout successful    
            break;    
        default:    
            // Other exceptions    
            break;    
    }    
});

API Reference: AuthV4.Helper.signOut

import com.hive.AuthV4
import com.hive.ResultAPI

AuthV4.Helper.signOut(object : AuthV4.Helper.AuthV4HelperListener {
    override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        when (result.code) {
            ResultAPI.Code.Success -> {
                // Logout successful
            }
            else -> {
                // Other exceptional situations
            }
        }
    }
})

API Reference: AuthV4.Helper.signOut

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.Helper.signOut((result, playerInfo) -> {
    switch (result.getCode()) {
        case Success:
            // Logout successful
            break;
        default:
            // Other exceptions
            break;
    }
});

API Reference: AuthV4Interface.helper().signOut()

import HIVEService

AuthV4Interface.helper().signOut() { result, playerInfo in
    switch result.getCode() {
        case .success:
            // Logout successful
        default:
            // Other exceptions
            break
    }}

API Reference: [HIVEAuthV4 helper] signOut

#import <HIVEService/HIVEService-Swift.h>

[[HIVEAuthV4 helper] signOut: ^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
    switch ([result getCode]) {
        case HIVEResultAPICodeSuccess:
            // Login successful
            break;
        default:
            // Other exceptions
            break;
    }
}];

Game Center Cancellation Notice Text

Language Phrase
Korean Apple Game Center login has been canceled.
Please log in at [Settings > Game Center] to sync with your Game Center account and try again.
English Your login to the Game Center has been canceled.
Log in at [Settings> Game Center] to sync to the Game Center Account and try again.
Japanese Apple Game Center login has been canceled.
Please log in at [Settings > Game Center] to try again after syncing with your Game Center account.
Simplified Chinese Apple Game Center has logged out.
If you want to sync with the Game Center account, please log in again in [Settings> Game Center] and try again.
Traditional Chinese Login to Apple Game Center has been canceled.
If you want to link to the Game Center account, please log in at [Settings > Game Center] and try again.
French Your connection to the Game Center has been canceled.
Log in at [Settings > Game Center] to sync your Game Center account and try again.
German The login to the Apple Game Center has been canceled.
Sync with the Game Center account by logging in at [Settings > Game Center] and try again.
Russian Your login to the Game Center has been canceled.
Log in to the Game Center through [Settings > Game Center] and try again.
Spanish Your login to Game Center has been canceled.
Log in at [Settings> Game Center] to sync with the Game Center account and try again.
Portuguese Your login to the Game Center has been canceled.
Log in at [Settings> Game Center] to sync with the Game Center account and try again.
Indonesian Login to Apple Game Center has been canceled.
Connect your Game Center account by logging in at [Settings > Game Center] and try again.
Malaysian Your login to the Game Center has been canceled.
Log in at [Settings> Game Center] to sync with the Game Center account and try again.
Vietnamese Login to Apple Game Center has been canceled.
Log in at [Settings > Game Center] to sync with your Game Center account and try again.
Thai Your login to the Game Center has been canceled.
Log in at [Settings> Game Center] to connect to your Game Center account and try again.
Italian Your access to the Apple Game Center has been canceled.
Log in at [Settings > Game Center] to sync your account with the Game Center and try again.
Turkish Your login to the Apple Game Center has been canceled.
Log in at [Settings> Game Center] to access the Game Center account and try again.
Arabic Your login to the Game Center has been canceled.
Log in at [Settings> Game Center] to sync with your Game Center account and try again.