GPGS -> 뒤끝 안드로이드 변경 후 빌드시 오류관련

고객님의 문의에 답변하는 직원은 고객 여러분의 가족 중 한 사람일 수 있습니다.
고객의 언어폭력(비하, 조롱, 욕설, 협박, 성희롱 등)으로부터 직원을 보호하기 위해
관련 법에 따라 수사기관에 필요한 조치를 요구할 수 있으며, 형법에 의해 처벌 대상이 될 수 있습니다.

커뮤니티 이용 정책에 위배되는 게시물을 작성할 경우, 별도 안내 없이 게시물 삭제 또는 커뮤니티 이용이 제한될 수 있습니다.

문의 응대 : 평일 오전 10시 ~ 오후 6시
문의를 남기실 경우 다음 항목을 작성해 주세요.
정보가 부족하거나 응대시간 외 문의하는 경우 확인 및 답변이 지연될 수 있습니다.

  • 뒤끝 SDK 버전 :
  • 프로젝트명 :
  • 스테이터스 코드 :
  • 에러 코드 : CommandInvokationFailure: Gradle build failed.
    C:\Program Files\Unity\Hub\Editor\2021.3.16f1-x86_64\Editor\Data\PlaybackEngines\AndroidPlayer\OpenJDK\bin\java.exe -classpath “C:\Program Files\Unity\Hub\Editor\2021.3.16f1-x86_64\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-7.6.4.jar” org.gradle.launcher.GradleMain “-Dorg.gradle.jvmargs=-Xmx4096m” “assembleRelease”

Environment Variables:
PROCESSOR_ARCHITECTURE = AMD64
JAVA_HOME = C:\Program Files\Unity\Hub\Editor\2021.3.16f1-x86_64\Editor\Data\PlaybackEngines\AndroidPlayer\OpenJDK
EFC_18256 = 1
DriverData = C:\Windows\System32\Drivers\DriverData
USERDOMAIN = DESKTOP-5Q7C4H1
CommonProgramFiles(x86) = C:\Program Files (x86)\Common Files
COMPUTERNAME = DESKTOP-5Q7C4H1
DEBUG_ENV_VAR = UnityHub
LOGONSERVER = \DESKTOP-5Q7C4H1
AMPLITUDE_TOKEN_GREENBUCKET_PROD = yyzPzalJDwrQcYNuOZam0bhKb26WyyhK
AMPLITUDE_API_KEY_YELLOWBUCKET_DEV = 48835b4d1f5e342aefe5f016324d296a
ProgramData = C:\ProgramData
SESSIONNAME = Console
AMPLITUDE_TOKEN_YELLOWBUCKET_PROD = Ph-837Q6GNodAkyc2MRkxVPUcjlIET4d
USERPROFILE = C:\Users\shtjd
ALLUSERSPROFILE = C:\ProgramData
SystemRoot = C:\WINDOWS
windir = C:\WINDOWS
AMPLITUDE_API_KEY_REDBUCKET_DEV = 46b8b46515e7632fc42a504b72e05fd0
ProgramFiles(x86) = C:\Program Files (x86)
ProgramW6432 = C:\Program Files
OS = Windows_NT
PROCESSOR_IDENTIFIER = AMD64 Family 25 Model 97 Stepping 2, AuthenticAMD
HEAP_CLIENT_TOKEN_STAGING = 3786794399
HOMEPATH = \Users\shtjd
FPS_BROWSER_USER_PROFILE_STRING = Default
AMPLITUDE_TOKEN_REDBUCKET_DEV = U4PSN7S7PuYVRODivvdcFwbu8R6IHGqa
CHROME_CRASHPAD_PIPE_NAME = \.\pipe\crashpad_31856_THLBXVOXKKTGDEJZ
PROCESSOR_LEVEL = 25
JAVA_TOOL_OPTIONS = -Dfile.encoding=UTF-8
CommonProgramFiles = C:\Program Files\Common Files
PUBLIC = C:\Users\Public
USERDOMAIN_ROAMINGPROFILE = DESKTOP-5Q7C4H1
TEMP = C:\Users\shtjd\AppData\Local\Temp
ProgramFiles = C:\Program Files
CommonProgramW6432 = C:\Program Files\Common Files
AMPLITUDE_TOKEN_YELLOWBUCKET_DEV = wKi8foVigDditGFvmZewRFWsEbX9Y0YO
AMPLITUDE_API_KEY_GREENBUCKET_DEV = 3ded2a762163603391a425f688f990c8
AMPLITUDE_API_KEY_REDBUCKET_PROD = ca12bb461ea96f9bdf5df4ded7d52994
HOMEDRIVE = C:
AMPLITUDE_API_KEY_STAGING = 83ee04fccc67e4fcc7dd527c4c6f1e21
USERNAME = shtjd
OneDrive = C:\Users\shtjd\OneDrive
AMPLITUDE_API_KEY_YELLOWBUCKET_PROD = e03a9bbe92dc38a88cdb068d24c65b46
PATHEXT = .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
AMPLITUDE_TOKEN_REDBUCKET_PROD = QqyoFpcWPi7V17p80_46CF6-sNGRGbHo
NUMBER_OF_PROCESSORS = 12
AMPLITUDE_TOKEN_GREENBUCKET_DEV = 84H2gMm_FJzhr3mBaX1lM1JVukmCM7d9
AMPLITUDE_DEPLOYMENT_KEY_RED_BUCKET_DEV = client-wbjHYrmeSR87GmWOE7LDpf7sUySOIKHm
AMPLITUDE_API_KEY_GREENBUCKET_PROD = c86fea37a9e1d3f0878b96e15b111c7c
ComSpec = C:\WINDOWS\system32\cmd.exe
ORIGINAL_XDG_CURRENT_DESKTOP = undefined
PROCESSOR_REVISION = 6102
AMPLITUDE_DEPLOYMENT_KEY_RED_BUCKET_PROD = client-zH8Y7OK1i331EKuG77C6UxN8ygcM6LzS
TMP = C:\Users\shtjd\AppData\Local\Temp
SystemDrive = C:
AMPLITUDE_API_KEY = 28f3cae0b33b8b3702120c9ed1a935aa
SENTRY_ACCESS_TOKEN = 3df78d9e53f8456aa90fbae044ce1a6261421ab1d0014674bc2e933477289017
HEAP_CLIENT_TOKEN = 1717415662
APPDATA = C:\Users\shtjd\AppData\Roaming
Path = C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\WINDOWS\System32\OpenSSH;C:\Program Files\Microsoft SQL Server\150\Tools\Binn;C:\Program Files\Git\cmd;C:\Program Files\dotnet;D:\Program Files\Nox\bin;C:\Users\shtjd\AppData\Local\Microsoft\WindowsApps;C:\Users\shtjd.dotnet\tools
PSModulePath = C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
LOCALAPPDATA = C:\Users\shtjd\AppData\Local
FPS_BROWSER_APP_PROFILE_STRING = Internet Explorer
WOOTRIC_CLIENT_TOKEN = NPS-aa8be4c3

stderr[

FAILURE: Build failed with an exception.

  • What went wrong:
    Could not determine the dependencies of task ‘:launcher:lintVitalRelease’.

This project uses AndroidX dependencies, but the ‘android.useAndroidX’ property is not enabled. Set this property to true in the gradle.properties file and retry.
The following AndroidX dependencies are detected: androidx.core:core:1.6.0, androidx.room:room-runtime:2.2.5, androidx.fragment:fragment:1.0.0, androidx.slidingpanelayout:slidingpanelayout:1.0.0, androidx.versionedparcelable:versionedparcelable:1.1.1, androidx.customview:customview:1.0.0, androidx.swiperefreshlayout:swiperefreshlayout:1.0.0, androidx.sqlite:sqlite:2.1.0, androidx.interpolator:interpolator:1.0.0, androidx.annotation:annotation-experimental:1.1.0, androidx.loader:loader:1.0.0, androidx.sqlite:sqlite-framework:2.1.0, androidx.drawerlayout:drawerlayout:1.0.0, androidx.collection:collection:1.1.0, androidx.viewpager:viewpager:1.0.0, androidx.work:work-runtime:2.7.0, androidx.localbroadcastmanager:localbroadcastmanager:1.0.0, androidx.arch.core:core-common:2.1.0, androidx.annotation:annotation:1.5.0, androidx.lifecycle:lifecycle-service:2.1.0, androidx.startup:startup-runtime:1.0.0, androidx.concurrent:concurrent-futures:1.1.0, androidx.room:room-common:2.2.5, androidx.lifecycle:lifecycle-common:2.1.0, androidx.lifecycle:lifecycle-livedata:2.1.0, androidx.tracing:tracing:1.0.0, androidx.legacy:legacy-support-core-ui:1.0.0, androidx.lifecycle:lifecycle-viewmodel:2.0.0, androidx.browser:browser:1.4.0, androidx.lifecycle:lifecycle-livedata-core:2.1.0, androidx.arch.core:core-runtime:2.1.0, androidx.legacy:legacy-support-core-utils:1.0.0, androidx.documentfile:documentfile:1.0.0, androidx.cursoradapter:cursoradapter:1.0.0, androidx.lifecycle:lifecycle-runtime:2.1.0, androidx.coordinatorlayout:coordinatorlayout:1.0.0, androidx.asynclayoutinflater:asynclayoutinflater:1.0.0, androidx.print:print:1.0.0

  • Try:

Run with --stacktrace option to get the stack trace.
Run with --info or --debug option to get more log output.
Run with --scan to get full insights.

BUILD FAILED in 5s
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
]
stdout[
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details

Configure project :launcher
WARNING: The option setting ‘android.enableR8=true’ is deprecated.
It will be removed in version 5.0 of the Android Gradle plugin.
You will no longer be able to disable R8

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.

You can use ‘–warning-mode all’ to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

See Command-Line Interface
]
exit code: 1
UnityEditor.Android.Command.WaitForProgramToRun (UnityEditor.Utils.Program p, UnityEditor.Android.Command+WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg) (at :0)
UnityEditor.Android.Command.Run (System.Diagnostics.ProcessStartInfo psi, UnityEditor.Android.Command+WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg) (at :0)
UnityEditor.Android.Command.Run (System.String command, System.String args, System.String workingdir, UnityEditor.Android.Command+WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg) (at :0)
UnityEditor.Android.AndroidJavaTools.RunJava (System.String args, System.String workingdir, System.Action1[T] progress, System.String error) (at <eb597642bbca4ce2aa0c70543523a5c8>:0) UnityEditor.Android.GradleWrapper.Run (UnityEditor.Android.AndroidJavaTools javaTools, Unity.Android.Gradle.AndroidGradle androidGradle, System.String workingdir, System.String task, System.Action1[T] progress) (at :0)
Rethrow as GradleInvokationException: Gradle build failed
UnityEditor.Android.GradleWrapper.Run (UnityEditor.Android.AndroidJavaTools javaTools, Unity.Android.Gradle.AndroidGradle androidGradle, System.String workingdir, System.String task, System.Action`1[T] progress) (at :0)
UnityEditor.Android.PostProcessor.Tasks.BuildGradleProject.Execute (UnityEditor.Android.PostProcessor.PostProcessorContext context) (at :0)
UnityEditor.Android.PostProcessor.PostProcessRunner.RunAllTasks (UnityEditor.Android.PostProcessor.PostProcessorContext context) (at :0)
Rethrow as BuildFailedException: Exception of type ‘UnityEditor.Build.BuildFailedException’ was thrown.
UnityEditor.Android.PostProcessor.CancelPostProcess.AbortBuild (System.String title, System.String message, System.Exception ex) (at :0)
UnityEditor.Android.PostProcessor.PostProcessRunner.RunAllTasks (UnityEditor.Android.PostProcessor.PostProcessorContext context) (at :0)
UnityEditor.Android.PostProcessAndroidPlayer.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args, AndroidPlayerBuildProgram.Data.AndroidPlayerBuildProgramOutput buildProgramOutput) (at :0)
UnityEditor.Android.AndroidBuildPostprocessor.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args, UnityEditor.BuildProperties& outProperties) (at :0)
UnityEditor.PostprocessBuildPlayer.Postprocess (UnityEditor.BuildTargetGroup targetGroup, UnityEditor.BuildTarget target, System.Int32 subtarget, System.String installPath, System.String companyName, System.String productName, System.Int32 width, System.Int32 height, UnityEditor.BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry, UnityEditor.Build.Reporting.BuildReport report) (at <11d97693183d4a6bb35c29ae7882c66b>:0)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

이게 Gradle 버전호환문제인지 아니면 빌드 셋팅문제인지 모르겠습니다. Gradle도 최신버전으로 업데이트를했는데도 이런 현상이 이러나네요
Gradle 프로젝트 셋팅은 이렇게되어있습니다.
image

안녕하세요, 개발자님.
뒤끝 플러그인 SDK를 제거해도 동일한 에러가 발생하는지 확인 요청드립니다.

작성하신 TheBackend.Toolkit 함수는 잠깐 주석처리 해주시고,
TheBackend > Toolkit > GoogleLogin > Android 폴더를 삭제하고, Android Dependency Resolver 에서 Force Resolve 호출하여 빌드 해주시면 감사하겠습니다.

아 저렇게하니 빌드 자체는 된거 같습니다. 혹시 안드로이드 로그인시 statusCode : 400 이뜨는데 이거는 토큰 관련 문제인거죠?

혹시 싶어 로그인 스크립트를 기재해봅니다
using UnityEngine;
using BackEnd;
using TMPro;
using System.Collections;
using UnityEngine.SceneManagement;
using LitJson;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Linq;
using AppleAuth;
using AppleAuth.Interfaces;
using System.Text;
using UnityEngine.Audio;
using UnityEditor;
using UnityEngine.Android;
using System;
#if UNITY_IOS
using Unity.Advertisement.IosSupport;
#endif
public class LoginManager : MonoSingleton
{
public static string myNickname => Backend.UserNickName;
public static string myInDate => Backend.UserInDate;

[SerializeField] private AudioMixer mixer = null;
public enum LoginType { Guest, OSLoginWithGoogle, OSLoginWithGoogleAndGuest };
[Header("로그인방식")]
[SerializeField] LoginType loginType = LoginType.Guest;

[Header("시즌 초기화")]
[SerializeField] bool isInitSeason = false;

[Header("UI")]
[SerializeField] GameObject bgImage = null;
[SerializeField] Button blockButton = null;
[SerializeField] SimpleButton creditButton = null;
[SerializeField] SimpleButton googleBtn = null;
[SerializeField] SimpleButton googleLoginBtn = null;
[SerializeField] SimpleButton guestBtn = null;
[SerializeField] SimpleButton touchToStart = null;
[SerializeField] Image platformImg = null;
[SerializeField] TextMeshProUGUI enteringText = null;

[SerializeField] NicknamePopUp nicknamePopUp = null;
[SerializeField] CreditPopUp creditPopUp = null;
[SerializeField] AgreementPopUp agreementPopUp = null;
[SerializeField] UpdatePopUp updatePopUp = null;
[SerializeField] InternetCheckPopUp internetCheckPopUp = null;
[SerializeField] BlockUserErrorPopUp blockUserErrorPopUp = null;
[SerializeField] SystemMaintenancePopUp systemMaintenancePopUp = null;
[SerializeField] DeletedPopUp deletedPopUp = null;
[SerializeField] GuestWarningPopUp guestWarningPopUp = null;
[SerializeField] GridLayoutGroup buttonsLayoutGroup = null;
BackendReturnObject bro = new BackendReturnObject();
public bool IsInitSeason => isInitSeason;
private bool isClicked = false;

bool isFirst, isLogin;
bool isConnectNetwork;
public bool CheckNetwork => isConnectNetwork;
public LoginType _LoginType => loginType;

public AppleAuthManager authManager;

string ios_token;
public string ios_google_token = null;


string Android_token;
public string Android_google_token = null;


[SerializeField] TextMeshProUGUI randomInfoTxt = null;

private bool isConnected = false;
public bool IsConnected { get { return isConnected; } private set { isConnected = value; } }    //연결 끊겼을때 친구 리스트 못 받게하기 위한 변수
private bool checkTryConnect;
protected override void Awake()
{
    base.Awake();
    SetResolution();
    DontDestroyOnLoad(this.gameObject);
    Initilize();
    LanguageSetting();
    Time.timeScale = 1;
}
public bool isgoogleFed = false;
private void Start()
{

#if UNITY_ANDROID && !UNITY_EDITOR
// InitializeAndroidLocalPush();
BackendFederation.Android.OnGoogleLogin += (bool isSuccess, string errorMessage, string token) =>
{
if(SceneManager.GetActiveScene().name != “02.MainScene”)
{
if (isSuccess == false)
{
Debug.LogError(errorMessage);
agreementPopUp.Show();
return;
}
var loginBro = Backend.BMember.AuthorizeFederation(token, FederationType.Google);
Android_google_token = token;
Debug.Log("로그인 결과 : " + loginBro);
if (loginBro.IsSuccess())
SetNickname();
else
{
agreementPopUp.Show();
if (loginBro.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
}
}
else
{
if(isSuccess)
{
Android_google_token = token;
isgoogleFed = true;
}
}
};
#endif

#if UNITY_IOS
BackendFederation.iOS.OnGoogleLogin += (bool isSuccess, string errorMessage, string token) =>
{
if(SceneManager.GetActiveScene().name != “02.MainScene”)
{
if (isSuccess == false)
{
Debug.LogError(errorMessage);
agreementPopUp.Show();
return;
}
var loginBro = Backend.BMember.AuthorizeFederation(token, FederationType.Google);
ios_google_token = token;
Debug.Log("로그인 결과 : " + loginBro);
if (loginBro.IsSuccess())
SetNickname();
else
{
agreementPopUp.Show();
if (loginBro.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
}
}
else
{
if(isSuccess)
{
ios_google_token = token;
isgoogleFed = true;
}
}
};
#endif

    StartCoroutine(Login());
    SoundManager.Instance.PlayAudioLoop("BGM_LOGIN_01");
    mixer.SetFloat("BGMVolume", Mathf.Log10(0.5f) * 30);
    mixer.SetFloat("FXVolume", Mathf.Log10(0.5f) * 30);
}


private void Update()
{
    Backend.AsyncPoll();

    if (authManager != null)
    {
        authManager.Update();
    }
}

protected override void OnApplicationQuit()
{
    base.OnApplicationQuit();
    Backend.Notification.DisConnect();  //  실시간 알림 서버 연결 해제
}
public void SetResolution()
{
    int setWidth = 1280; // 사용자 설정 너비
    int setHeight = 720; // 사용자 설정 높이

    int deviceWidth = Screen.width; // 기기 너비 저장
    int deviceHeight = Screen.height; // 기기 높이 저장

    Screen.SetResolution(setWidth, (int)(((float)deviceHeight / deviceWidth) * setWidth), true); // SetResolution 함수 제대로 사용하기

    if ((float)setWidth / setHeight < (float)deviceWidth / deviceHeight) // 기기의 해상도 비가 더 큰 경우
    {
        float newWidth = ((float)setWidth / setHeight) / ((float)deviceWidth / deviceHeight); // 새로운 너비
        Camera.main.rect = new Rect((1f - newWidth) / 2f, 0f, newWidth, 1f); // 새로운 Rect 적용
    }
    else // 게임의 해상도 비가 더 큰 경우
    {
        float newHeight = ((float)deviceWidth / deviceHeight) / ((float)setWidth / setHeight); // 새로운 높이
        Camera.main.rect = new Rect(0f, (1f - newHeight) / 2f, 1f, newHeight); // 새로운 Rect 적용
    }
}
void Initilize()
{
    isFirst = true;
    isLogin = false;
    isConnectNetwork = false;

    googleBtn.OnClick.AddListener(() =>
    {
        SoundManager.Instance.PlayAudio("UIClick");
        GPGSLogin();
    });
    googleLoginBtn.OnClick.AddListener(() =>
    {
        SoundManager.Instance.PlayAudio("UIClick");
        IosGoogleLogin();
    });
    guestBtn.OnClick.AddListener(() =>
    {
        SoundManager.Instance.PlayAudio("UIClick");
        guestWarningPopUp.Show();
    });
    creditButton.OnClick.AddListener(() =>
    {
        SoundManager.Instance.PlayAudio("UIClick");
        creditPopUp.Show();
    });
    blockButton.onClick.AddListener(() => isClicked = true);

    creditButton.gameObject.SetActive(false);
    enteringText.gameObject.SetActive(false);
    touchToStart.gameObject.SetActive(false);

#if UNITY_IOS
// Check the user’s consent status.
// If the status is undetermined, display the request request:
if(ATTrackingStatusBinding.GetAuthorizationTrackingStatus() == ATTrackingStatusBinding.AuthorizationTrackingStatus.NOT_DETERMINED) {
ATTrackingStatusBinding.RequestAuthorizationTracking();
}
#endif
LocalizationTable.LoadLanguageSheet();
LocalizationTable.languageSettings += LanguageSetting;
Utility.LoadNicknameFilter();
UIUtility.LoadColorCode();
UIUtility.OnLoadAllSprite();

#if UNITY_ANDROID
platformImg.sprite = UIUtility.GetUISprite(“Google_Logo_128”);
platformImg.color = new Color(1, 1, 1);
#elif UNITY_IOS
platformImg.sprite = UIUtility.GetUISprite(“Apple_Logo_128”);
platformImg.color = new Color(0, 0, 0);
#endif

    /*
     * 약관동의, 닉네임, 만든이 팝업들을 비활성화 상태에서 실행 시 Awake의 초기화를 실행하지 못하고
     * Show() 호출 시 초기화를 진행하여 Close()를 호출하기 때문에
     * LoginScene에서 비활성화를 하기 위해서 LoginManager 초기화 시 해당 팝업들의 Show()를 미리 호출
     */
    agreementPopUp.Show();
    nicknamePopUp.Show();
    creditPopUp.Show();
    updatePopUp.Show();
    internetCheckPopUp.Show();
    blockUserErrorPopUp.Show();
    systemMaintenancePopUp.Show();
    deletedPopUp.Show();
    guestWarningPopUp.Show();
}

void LanguageSetting()
{
    creditButton.SetText(LocalizationTable.Localization("Login_Credit"));

#if UNITY_ANDROID
googleBtn.SetText(LocalizationTable.Localization(“Login_Google”));
#elif UNITY_IOS
googleBtn.SetText(LocalizationTable.Localization(“Login_Apple”));
googleLoginBtn.SetText(LocalizationTable.Localization(“Login_Google”));
#endif
guestBtn.SetText(LocalizationTable.Localization(“Login_Guest”));
}
//서버 상태 주기적으로 확인하기 위한 함수
IEnumerator OnNetworkCheck()
{
WaitForSecondsRealtime wait = new WaitForSecondsRealtime(3600);
bool isDuplicationLogin = false;

    while (true)
    {
        if (isLogin)
            break;

        Backend.Utils.GetServerStatus((callback) =>
        {
            if (callback.IsSuccess())
            {
                isConnectNetwork = true;
                Debug.Log("현재 서버 상태 : " + callback.GetReturnValuetoJSON()[0]);
                if (callback.GetReturnValuetoJSON()[0].Equals(2))
                {
                    if (!systemMaintenancePopUp.gameObject.activeSelf)
                        systemMaintenancePopUp.Show2();
                }
            }
            else
            {
                if (callback.GetErrorCode() == "HttpRequestException")
                {
                    isConnectNetwork = false;

                    if (!internetCheckPopUp.gameObject.activeSelf)
                        internetCheckPopUp.Show();
                }

            }
        });

        yield return wait;
    }

    while (true)
    {
        if (isDuplicationLogin)
            yield break;

        Backend.BMember.IsAccessTokenAlive((callback) =>
        {
            if (callback.IsSuccess())
            {
                isConnectNetwork = true;
            }
            else
            {
                if (callback.GetErrorCode() == "HttpRequestException")
                {
                    isConnectNetwork = false;

                    if (SceneManager.GetActiveScene().buildIndex == 1)
                    {
                        if (!internetCheckPopUp.gameObject.activeSelf)
                            internetCheckPopUp.Show();
                    }
                    else if (SceneManager.GetActiveScene().buildIndex == 2)
                    {
                        GameManager.Instance.isLocal = true;

                        if (!UIManager.Instance.internetErrorPopUp.gameObject.activeSelf)
                            UIManager.Instance.internetErrorPopUp.Show();
                    }
                }
                else if (callback.GetErrorCode() == "BadUnauthorizedException")
                {
                    UIManager.Instance.duplicationLoginPopUp.Show2();
                    isDuplicationLogin = true;
                }
                else
                {
                    Debug.Log($"StatusCode : {callback.GetStatusCode()}, message : {callback.GetMessage()}");
                }
            }
        });

        yield return wait;
    }
}

void HandleBackendCallback(BackendReturnObject bro)
{
    if (bro.IsSuccess())
    {
        // 구글 해시키 획득 
        if (!Backend.Utils.GetGoogleHash().Equals(""))
            Debug.Log(Backend.Utils.GetGoogleHash());

        // 서버시간 획득
        Debug.Log(Backend.Utils.GetServerTime());

        Backend.Notification.OnAuthorize = (bool result, string reason) =>
        {
            if (result)
            {
                IsConnected = true;
                checkTryConnect = false;
            }
            else
            {
                if (checkTryConnect)
                {
                    return;
                }
                checkTryConnect = true;
                Invoke(nameof(Reconnected), 5f);
            }

            Debug.Log($"실시간 서버 연결 : {result}, {reason}");
        };
        Backend.Notification.OnDisConnect = (string reason) =>
        {
            IsConnected = false;
            Debug.Log(reason);
        };

        StartCoroutine(OnNetworkCheck());
    }
    // 실패
    else
    {
        Debug.LogError("Failed to initialize the backend");
        if (!internetCheckPopUp.gameObject.activeSelf)
        {
            internetCheckPopUp.Show();
            Destroy(gameObject);
        }
    }
}

private void Reconnected()
{
    checkTryConnect = false;
    Backend.Notification.Connect();
}

#region Guest Login
public void GuestLogin()
{
    bro = Backend.BMember.GuestLogin();

    PlayerPrefs.SetString("LoginType", "Guest");
    PlayerPrefs.SetInt("IsFirst", 1);
    PlayerPrefs.Save();

    if (bro.IsSuccess() == false)
    {
        Debug.Log(bro.GetMessage());
        if (bro.GetMessage().Contains("bad customId"))
        {
            DeleteGuestInfo();
            GuestLogin();
        }
        if (bro.GetMessage().Contains("blocked user"))
        {
            blockUserErrorPopUp.Show();
        }
        if (bro.GetMessage().Contains("Gone user"))
        {
            deletedPopUp.Show();
        }
    }
    else if (bro.GetStatusCode() == "201")
    {
        if (PlayerPrefs.GetInt("IsNewUser") == 0)
        {
            agreementPopUp.Show();
        }
        else if (PlayerPrefs.GetInt("IsNewUser") == 2)
        {
            PlayerPrefs.SetInt("IsNewUser", 1);
            PlayerPrefs.Save();
            SetNickname();
        }
    }
    else
    {
        if (PlayerPrefs.GetInt("IsNewUser") == 1)
        {
            PlayerPrefs.DeleteAll();
            agreementPopUp.Show();
        }
        else
            SetNickname();
    }
}

void DeleteGuestInfo()
{
    Debug.Log("-------------DeleteGuestInfo-------------");
    Backend.BMember.DeleteGuestInfo();
}
#endregion

#region Google Login
void GPGSLogin()
{

#if UNITY_EDITOR
Debug.LogError(“에디터에서는 구글 로그인이 불가능합니다.”);
#elif UNITY_ANDROID
PlayerPrefs.SetString(“LoginType”, “Google”);
PlayerPrefs.SetInt(“IsFirst”, 1);
PlayerPrefs.Save();
#elif UNITY_IOS
PlayerPrefs.SetString(“LoginType”, “Apple”);
PlayerPrefs.SetInt(“IsFirst”, 1);
PlayerPrefs.Save();
#endif

    GoogleLogin(false, false);
}
IEnumerator IOSLogin(bool async, bool changeFed)
{
    bool isSuccess = false;
    if (ios_token == null)
    {
        if (authManager == null)
            authManager = new AppleAuthManager(new AppleAuth.Native.PayloadDeserializer());
        authManager.LoginWithAppleId(AppleAuth.Enums.LoginOptions.IncludeEmail | AppleAuth.Enums.LoginOptions.IncludeFullName,
            success =>
            {
                var appleIdCredential = success as IAppleIDCredential;
                ios_token = Encoding.UTF8.GetString(appleIdCredential.IdentityToken);
                Debug.Log($"Apple Login Success {ios_token}");
                isSuccess = true;
            },
            error =>
            {
                Debug.Log($"Apple LoginError {error}");
                agreementPopUp.Show();
            });
    }
    yield return new WaitUntil(() => isSuccess);
    // 이미 로그인 된 경우
    if (Social.localUser.authenticated == true)
    {
        Debug.Log("8");
        BackendAuthorize(async, changeFed);
        Debug.Log("9");
    }
    else
    {
        BackendAuthorize(async, changeFed);
    }
}
void GoogleLogin(bool async, bool changeFed)
{
    Debug.Log("7");

#if UNITY_IOS
StartCoroutine(IOSLogin(async, changeFed));
#else
// 이미 로그인 된 경우
if (Social.localUser.authenticated == true)
{
Debug.Log(“8”);
BackendAuthorize(async, changeFed);
Debug.Log(“9”);
}
else
{
Debug.Log(“10”);
Social.localUser.Authenticate((success, errorMessage) =>
{
Debug.Log(“11”);
Debug.Log($“Login {(success ? “Success” : “Failed”)}”);
if (success)
{
Debug.Log(“12”);
// 로그인 성공 → 뒤끝 서버에 획득한 구글 토큰으로 가입요청
BackendAuthorize(async, changeFed);
Debug.Log(“13”);
}
else
{
// 로그인 실패
Debug.Log(“Login failed for some reason\n” + errorMessage);
}
});
}
#endif
}

public void BackendAuthorize(bool async, bool changeFed)
{
    // 커스텀 -> 페더레이션 변경
    if (changeFed)
    {
        // 비동기
        if (async)
        {

#if UNITY_ANDROID
Backend.BMember.ChangeCustomToFederation(GetTokens(), FederationType.Google, isComplete =>
{
Debug.Log(isComplete.ToString());
if (isComplete.IsSuccess())
{
if (isComplete.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}
else
{
if (isComplete.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (isComplete.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
});
#elif UNITY_IOS
Backend.BMember.ChangeCustomToFederation(GetTokens(), FederationType.Apple, isComplete =>
{
Debug.Log(isComplete.ToString());
if (isComplete.IsSuccess())
{
if (isComplete.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}
else
{
if (isComplete.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (isComplete.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
});
#endif
}
// 동기
else
{
#if UNITY_ANDROID
BackendReturnObject BRO = Backend.BMember.ChangeCustomToFederation(GetTokens(), FederationType.Google);
Debug.Log(BRO);
#elif UNITY_IOS
BackendReturnObject BRO = Backend.BMember.ChangeCustomToFederation(GetTokens(), FederationType.Apple);
Debug.Log(BRO);
#endif
if (BRO.IsSuccess())
{
if (BRO.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}
else
{
if (BRO.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (BRO.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
}
}
// 페더레이션 인증
else
{
// 비동기
if (async)
{
// AuthorizeFederation 대신 AuthorizeFederationAsync 사용
#if UNITY_ANDROID
Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, “gpgs”, callback =>
{
Debug.Log(callback);
if (callback.IsSuccess())
{
if (callback.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}

                else
                {
                    if (callback.GetMessage().Contains("blocked user"))
                        blockUserErrorPopUp.Show();
                    if (callback.GetMessage().Contains("Gone user"))
                    {
                        deletedPopUp.Show();
                    }
                }
            });

#elif UNITY_IOS
Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Apple, “siwa”, callback =>
{
Debug.Log(callback);
if (callback.IsSuccess())
{
if (callback.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}
else
{
if (callback.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (callback.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
});
#endif
}
// 동기
else
{
#if UNITY_ANDROID
BackendReturnObject BRO = Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, “gpgs”);
Debug.Log(BRO);
#elif UNITY_IOS
Debug.Log(“Before GetToken”);
BackendReturnObject BRO = Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Apple, “siwa”);
Debug.Log(“After GetToken”);
Debug.Log(BRO);
#endif
if (BRO.IsSuccess())
SetNickname();
else
{
if (BRO.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (BRO.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
}
}
}

public string GetTokens()
{

#if UNITY_ANDROI
return Android_token;D
#region googleplayGames 주석
//if (PlayGamesPlatform.Instance.localUser.authenticated)
//{
// // 유저 토큰 받기 첫번째 방법
// string _IDtoken = PlayGamesPlatform.Instance.GetIdToken();
// // 두번째 방법
// // string _IDtoken = ((PlayGamesLocalUser)Social.localUser).GetIdToken();
// Debug.Log(_IDtoken);
// return _IDtoken;
//}
//else
//{
// Debug.Log(“접속되어있지 않습니다. PlayGamesPlatform.Instance.localUser.authenticated : fail”);
//
//}
#endregion
#elif UNITY_IOS
return ios_token;
#else
return null;
#endif
}
#endregion

void IosGoogleLogin()
{

#if UNITY_EDITOR
Debug.LogError(“에디터에서는 구글 로그인이 불가능합니다.”);
#endif
PlayerPrefs.SetString(“LoginType”, “AppleGoogleLogin”);
PlayerPrefs.SetInt(“IsFirst”, 1);
PlayerPrefs.Save();

#if UNITY_IOS
if (Social.localUser.authenticated == true)
{
string message;
var result = BackendFederation.iOS.GoogleLogin(“852407933148-hkcqr8j7h0016emp5vvho9996be7r3t4.apps.googleusercontent.com”, out message);

        if (result == false)
        {
            Debug.LogError(message);
        }
    }
    else
    {
        string message;
        var result = BackendFederation.iOS.GoogleLogin("852407933148-hkcqr8j7h0016emp5vvho9996be7r3t4.apps.googleusercontent.com", out message);
        SetNickname();
        if (result == false)
        {
            Debug.LogError(message);
        }
    }

#endif
}

void AndroidGoogleLogin()
{

#if UNITY_EDITOR
Debug.LogError(“에디터에서는 구글 로그인이 불가능합니다.”);
#endif
PlayerPrefs.SetString(“LoginType”, “AndroidGoogleLogin”);
PlayerPrefs.SetInt(“IsFirst”, 1);
PlayerPrefs.Save();

#if UNITY_ANDROID
if (Social.localUser.authenticated == true)
{
string message;
var result = BackendFederation.Android.GoogleLogin(“852407933148-hkcqr8j7h0016emp5vvho9996be7r3t4.apps.googleusercontent.com”, out message);

        if (result == false)
        {
            Debug.LogError(message);
        }
    }
    else
    {
        string message;
        var result = BackendFederation.Android.GoogleLogin("852407933148-hkcqr8j7h0016emp5vvho9996be7r3t4.apps.googleusercontent.com", out message);
        SetNickname();
        if (result == false)
        {
            Debug.LogError(message);
        }
    }

#endif
}

public void ShowLoginButtons()
{
    isFirst = false;
    googleBtn.transform.parent.gameObject.SetActive(true);
    googleLoginBtn.gameObject.SetActive(false);
    switch (loginType)
    {
        case LoginType.Guest:
            googleBtn.gameObject.SetActive(false);
            googleLoginBtn.gameObject.SetActive(false);
            guestBtn.gameObject.SetActive(true);
            break;
        case LoginType.OSLoginWithGoogle:
            googleBtn.gameObject.SetActive(true);

#if UNITY_IOS
googleLoginBtn.gameObject.SetActive(true);
#endif
guestBtn.gameObject.SetActive(false);
break;
case LoginType.OSLoginWithGoogleAndGuest:
googleBtn.gameObject.SetActive(true);
#if UNITY_IOS
googleLoginBtn.gameObject.SetActive(true);
#endif
guestBtn.gameObject.SetActive(true);
break;
}
}

public void UpdateNickname(string name)
{
    bro = Backend.BMember.UpdateNickname(name);

    if (bro.IsSuccess())
    {
        isLogin = true;
        nicknamePopUp.Close();
        StartCoroutine(TouchToStart());

        //  유저 국가코드 설정
        BackEnd.GlobalSupport.CountryCode countryCode = BackEnd.GlobalSupport.CountryCode.NONE;

        if (Application.systemLanguage == SystemLanguage.Korean)
            countryCode = BackEnd.GlobalSupport.CountryCode.SouthKorea;
        else if (Application.systemLanguage == SystemLanguage.English)
            countryCode = BackEnd.GlobalSupport.CountryCode.UnitedStates;
        else if (Application.systemLanguage == SystemLanguage.Japanese)
            countryCode = BackEnd.GlobalSupport.CountryCode.Japan;
        else if (Application.systemLanguage == SystemLanguage.ChineseSimplified)
            countryCode = BackEnd.GlobalSupport.CountryCode.China;
        else if (Application.systemLanguage == SystemLanguage.ChineseTraditional)
            countryCode = BackEnd.GlobalSupport.CountryCode.Taiwan;
        else
            countryCode = BackEnd.GlobalSupport.CountryCode.UnitedStates;

        Backend.BMember.UpdateCountryCode(countryCode, callback =>
        {
            if (callback.IsSuccess())
                Debug.Log("국가 코드 설정 완료");
            else
                Debug.Log($"국가 코드 설정 실패 - statusCode : {callback.GetErrorCode()}, message : {callback.GetMessage()}");
        });
    }
    else
    {
        Debug.Log(bro.GetMessage());
        nicknamePopUp.OnNotice(bro.GetStatusCode());
    }
}

public string GetUserInDate(string nickName)
{
    var bro = Backend.Social.GetUserInfoByNickName(nickName);

    if (bro.IsSuccess())
    {
        JsonData rows = bro.GetReturnValuetoJSON()["row"];

        if (rows.Count > 0)
            return rows["inDate"].ToString();
        else
            return null;
    }

    return null;
}

IEnumerator LoadScene()
{
    AsyncOperation op = SceneManager.LoadSceneAsync("02.MainScene");
    op.allowSceneActivation = false;
    var delay = new WaitForSeconds(0.4f);
    enteringText.gameObject.SetActive(true);

    var strs = new[] { ".", "...", "..." };
    var i = 0;
    enteringText.text = LocalizationTable.Localization("Login_Enter");
    randomInfoTxt.text = LocalizationTable.Localization($"Login_GameInfo0{Global.Rand(1, 5)}");   //로그인화면 하단에 게임설명 표기 관련 >리스트가 추가될시 범위를 조정 함
    randomInfoTxt.gameObject.SetActive(true);

    while (!op.isDone)
    {
        enteringText.text += strs[i++];
        i %= strs.Length;
        yield return delay;

        if (op.progress >= 0.9f)
        {
            op.allowSceneActivation = true;
            yield break;
        }
    }
    yield return null;
}

IEnumerator TouchToStart()
{
    touchToStart.SetText(LocalizationTable.Localization("Login_Start"));

    bgImage.SetActive(false);
    touchToStart.gameObject.SetActive(true);
    creditButton.gameObject.SetActive(true);
    googleBtn.transform.parent.gameObject.SetActive(false);
    isClicked = false;

    //#if UNITY_ANDROID
    //        yield return null;
    //        while (!isClicked)
    //            yield return null;
    //#endif
    touchToStart.gameObject.SetActive(false);
    SoundManager.Instance.PlayAudio("UIClick");


    yield return null;

    StartCoroutine(LoadScene());
}

//private IEnumerator GetTokenIOS()
//{
//    //뒤끝 sdk 버전 업 후 ios 토큰을 못 받아오는 문제가 생겨
//    //수동으로 토큰을 받아i
//    var authOption = AuthorizationOption.Alert | AuthorizationOption.Badge;
//    using (var req = new AuthorizationRequest(authOption, true))
//    {
//        while (!req.IsFinished)
//        {
//            yield return null;
//        }


//        var bro2 = Backend.iOS.PutDeviceToken(req.DeviceToken, isDevelopment.iosProd);
//        if (bro2.IsSuccess())
//        {
//            Debug.Log($"푸시 알림 설정 성공 : {bro.ToString()}");
//        }
//        else
//        {
//            Debug.Log($"푸시 알림 설정 실패 - statusCode : {bro.GetErrorCode()}, message : {bro.GetMessage()}");
//        }
//    }
//}

IEnumerator Login()
{
    isFirst = PlayerPrefs.GetInt("IsFirst", 0) == 0;

    if (isFirst)
    {
        if (Application.systemLanguage == SystemLanguage.Korean)
            LocalizationTable.SetLanguage(ELanguage.KR);
        else if (Application.systemLanguage == SystemLanguage.English)
            LocalizationTable.SetLanguage(ELanguage.EN);
        else if (Application.systemLanguage == SystemLanguage.Japanese)
            LocalizationTable.SetLanguage(ELanguage.JP);
        else if (Application.systemLanguage == SystemLanguage.Chinese)
            LocalizationTable.SetLanguage(ELanguage.CN);
        else
            LocalizationTable.SetLanguage(ELanguage.EN);
    }
    else
    {
        string str = PlayerPrefs.GetString("Language");

        if (str == "KR")
            LocalizationTable.SetLanguage(ELanguage.KR);
        else if (str == "EN")
            LocalizationTable.SetLanguage(ELanguage.EN);
        else if (str == "JP")
            LocalizationTable.SetLanguage(ELanguage.JP);
        else if (str == "CN")
            LocalizationTable.SetLanguage(ELanguage.CN);
        else
            LocalizationTable.SetLanguage(ELanguage.EN);
    }

    // yield return new WaitUntil(() => !isFirst);

    Debug.Log("1");
    Backend.InitializeAsync(true, true, HandleBackendCallback);

#if UNITY_ANDROID
//PlayGamesClientConfiguration config = new PlayGamesClientConfiguration
// .Builder()
// .RequestServerAuthCode(false)
// .RequestEmail()
// .RequestIdToken()
// .Build();

    //PlayGamesPlatform.InitializeInstance(config);
    //// recommended for debugging:
    //PlayGamesPlatform.DebugLogEnabled = true;
    //// Activate the Google Play Games platform
    //PlayGamesPlatform.Activate();

#endif
Debug.Log(“2”);
if (!Backend.Utils.GetGoogleHash().Equals(""))
Debug.Log(Backend.Utils.GetGoogleHash());

    Debug.Log("3");

#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
yield return StartCoroutine(CheckVersion());
#endif
Debug.Log(“4”);
var isSuccess = false;
Social.localUser.Authenticate((success, errorMessage) =>
{
Debug.Log($“Login {(success ? “Success” : “Failed”)}”);

        isSuccess = true;
    });

    yield return new WaitUntil(() => isSuccess);

    yield return new WaitForSeconds(0.2f);

    BackendReturnObject bro2 = Backend.BMember.LoginWithTheBackendToken();
    if (bro2.IsSuccess())
    {
        SetNickname();
        yield break;
    }
    else
    {
        Debug.Log($"LoginWithTheBackendToken : {bro2.GetErrorCode()}");
    }

    var type = PlayerPrefs.GetString("LoginType");
    PlayerPrefs.SetInt("IsNewUser", 0);
    if (type == "Guest")
    {
        GuestLogin();
    }
    else if (type == "Google" || type == "Apple")
    {
        GPGSLogin();
    }
    else if (type == "AppleGoogleLogin")
    {
        IosGoogleLogin();
    }
    else if ((PlayerPrefs.GetInt("IsFirst") == 0))
    {
        agreementPopUp.Show();
    }
}

IEnumerator CheckVersion()
{
    bro = Backend.Utils.GetLatestVersion();

    if (bro.IsSuccess())
    {
        string version = bro.GetReturnValuetoJSON()["version"].ToString();

        if (version == Application.version)
            yield break;
        if (!CheckUpdate(version))
            yield break;

        bool forceUpdate = false;
        string updatetype = bro.GetReturnValuetoJSON()["type"].ToString();

        if (updatetype == "1")
        {
            //  선택 업데이트
            Debug.Log("업데이트를 하시겠습니까? y/n");
        }
        else if (updatetype == "2")
        {
            //  강제 업데이트
            forceUpdate = true;
            updatePopUp.Show2();
        }

        yield return new WaitUntil(() => (!forceUpdate));
    }
    else
    {
        Debug.LogError($"StatusCode : {bro.GetStatusCode()}\nErrorCode : {bro.GetErrorCode()}\nMessage : {bro.GetMessage()}");
    }
}

bool CheckUpdate(string version)
{
    int[] checkVersion = version.Split('.').Select(str => int.Parse(str)).ToArray();
    int[] myVersion = Application.version.Split('.').Select(str => int.Parse(str)).ToArray();

    if (myVersion[0] > checkVersion[0])
        return false;
    else if (myVersion[0] < checkVersion[0])
        return true;
    else
    {
        if (myVersion[1] > checkVersion[1])
            return false;
        else if (myVersion[1] < checkVersion[1])
            return true;
        else
        {
            if (myVersion[2] >= checkVersion[2])
                return false;
            else
                return true;
        }
    }
}

private void SetNickname()
{
    bro = Backend.BMember.GetUserInfo();
    if (bro.GetReturnValuetoJSON()["row"]["nickname"] == null)
    {
        if (PlayerPrefs.GetInt("IsNewUser") == 0)
        {
            agreementPopUp.Show();
            return;
        }
        ShowLoginButtons();

        buttonsLayoutGroup.CalculateLayoutInputHorizontal();
        buttonsLayoutGroup.CalculateLayoutInputVertical();
        buttonsLayoutGroup.SetLayoutHorizontal();
        buttonsLayoutGroup.SetLayoutVertical();

#if UNITY_ANDROID
nicknamePopUp.inputFieldPos = googleBtn.transform.position;
#elif UNITY_IOS
nicknamePopUp.inputFieldPos = googleLoginBtn.transform.position;
#endif
nicknamePopUp.Show();
googleBtn.transform.parent.gameObject.SetActive(false);
}
else
{
isLogin = true;
StartCoroutine(TouchToStart());
}
Backend.Notification.Connect(); // 실시간 알림 서버 연결

    //  푸시 알림 설정

#if !UNITY_EDITOR
#if UNITY_ANDROID
Backend.Android.PutDeviceToken(Backend.Android.GetDeviceToken(), (callback) =>
{
if (callback.IsSuccess())
{
Debug.Log($“푸시 알림 설정 성공 : {callback}”);
}
else
{
Debug.Log($“푸시 알림 설정 실패 - statusCode : {callback.GetErrorCode()}, message : {callback.GetMessage()}”);
}
});
#elif UNITY_IOS
StartCoroutine(GetTokenIOS());
//bro = Backend.iOS.PutDeviceToken(isDevelopment.iosProd);
//if (bro.IsSuccess())
//{
// Debug.Log($“푸시 알림 설정 성공 : {bro.ToString()}”);
//}
//else
//{
// Debug.Log($“푸시 알림 설정 실패 - statusCode : {bro.GetErrorCode()}, message : {bro.GetMessage()}”);
//}
//Backend.iOS.PutDeviceToken(isDevelopment.iosProd, (callback) =>
//{
// if (callback.IsSuccess())
// {
// Debug.Log($“푸시 알림 설정 성공 : {callback}”);
// }
// else
// {
// Debug.Log($“푸시 알림 설정 실패 - statusCode : {callback.GetErrorCode()}, message : {callback.GetMessage()}”);
// }
//});
#endif
#endif
}

public void ServerError(BackendReturnObject _bro)
{
    if (_bro.GetMessage().Contains("blocked user"))
    {

#if UNITY_EDITOR
EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
if (_bro.GetMessage().Contains(“maintenance”))
{
UIManager.Instance.duplicationLoginPopUp.Show2();
}
if (_bro.GetMessage().Contains(“Gone user”))
{
#if UNITY_EDITOR
EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
if (_bro.GetErrorCode().Contains(“accessToken”))
{
UIManager.Instance.duplicationLoginPopUp.Show2();
}
if (_bro.GetErrorCode().Contains(“refreshToken”))
{
UIManager.Instance.duplicationLoginPopUp.Show2();
}
if (_bro.GetErrorCode().Contains(“HttpRequestException”))
{
UIManager.Instance.internetErrorPopUp.Show();
}
}
}

네, 맞습니다.

스테이터스코드 : 400
에러 코드 : UndefinedParameterException
에러메시지 : undefined refresh_token, refresh_token을(를) 확인할 수 없습니다

에러 로그는 위와 같이 확인되며,
해당 에러의 경우 로그인에 사용되는 리프레시 토큰이 null일 경우 발생합니다.

페더레이션 변경하는 쪽에서나는거같은데 어떻게 수정해야할지 잘모르겠습니다.
public void BackendAuthorize(bool async, bool changeFed)
{
// 커스텀 → 페더레이션 변경
if (changeFed)
{
// 비동기
if (async)
{
#if UNITY_ANDROID
Backend.BMember.ChangeCustomToFederation(GetTokens(), FederationType.Google, isComplete =>
{
Debug.Log(isComplete.ToString());
if (isComplete.IsSuccess())
{
if (isComplete.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}
else
{
if (isComplete.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (isComplete.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
});
#elif UNITY_IOS
Backend.BMember.ChangeCustomToFederation(GetTokens(), FederationType.Apple, isComplete =>
{
Debug.Log(isComplete.ToString());
if (isComplete.IsSuccess())
{
if (isComplete.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}
else
{
if (isComplete.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (isComplete.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
});
#endif
}
// 동기
else
{
#if UNITY_ANDROID
BackendReturnObject BRO = Backend.BMember.ChangeCustomToFederation(GetTokens(), FederationType.Google);
Debug.Log(BRO);
#elif UNITY_IOS
BackendReturnObject BRO = Backend.BMember.ChangeCustomToFederation(GetTokens(), FederationType.Apple);
Debug.Log(BRO);
#endif
if (BRO.IsSuccess())
{
if (BRO.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}
else
{
if (BRO.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (BRO.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
}
}
// 페더레이션 인증
else
{
// 비동기
if (async)
{
// AuthorizeFederation 대신 AuthorizeFederationAsync 사용
#if UNITY_ANDROID
Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, “gpgs”, callback =>
{
Debug.Log(callback);
if (callback.IsSuccess())
{
if (callback.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}

                else
                {
                    if (callback.GetMessage().Contains("blocked user"))
                        blockUserErrorPopUp.Show();
                    if (callback.GetMessage().Contains("Gone user"))
                    {
                        deletedPopUp.Show();
                    }
                }
            });

#elif UNITY_IOS
Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Apple, “siwa”, callback =>
{
Debug.Log(callback);
if (callback.IsSuccess())
{
if (callback.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}
else
{
if (callback.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (callback.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
});
#endif
}
// 동기
else
{
#if UNITY_ANDROID
BackendReturnObject BRO = Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, “gpgs”);
Debug.Log(BRO);
#elif UNITY_IOS
Debug.Log(“Before GetToken”);
BackendReturnObject BRO = Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Apple, “siwa”);
Debug.Log(“After GetToken”);
Debug.Log(BRO);
#endif
if (BRO.IsSuccess())
SetNickname();
else
{
if (BRO.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (BRO.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
}
}
}
해당함수인데 도움을 받을수 있을까요

로그찍어보니 페더레이션 인증 하는곳에서 토큰을 못불러내는거같스빈다 혹시
Debug.Log(“패더레이션 인증 진입”);
// 비동기
if (async)
{
Debug.Log(" 비동기 패더레이션 인증 진입");
// AuthorizeFederation 대신 AuthorizeFederationAsync 사용
#if UNITY_ANDROID
Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, “gpgs”, callback =>
{

                Debug.Log(callback);
                if (callback.IsSuccess())
                {
                    if (callback.GetStatusCode() == "201")
                    {
                        if (PlayerPrefs.GetInt("IsNewUser") == 0)
                        {
                            agreementPopUp.Show();
                        }
                        else if (PlayerPrefs.GetInt("IsNewUser") == 2)
                        {
                            PlayerPrefs.SetInt("IsNewUser", 1);
                            PlayerPrefs.Save();
                            SetNickname();
                        }
                    }
                    else
                    {
                        SetNickname();
                    }
                }

                else
                {
                    if (callback.GetMessage().Contains("blocked user"))
                        blockUserErrorPopUp.Show();
                    if (callback.GetMessage().Contains("Gone user"))
                    {
                        deletedPopUp.Show();
                    }
                }
            });

#elif UNITY_IOS
Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Apple, “siwa”, callback =>
{
Debug.Log(callback);
if (callback.IsSuccess())
{
if (callback.GetStatusCode() == “201”)
{
if (PlayerPrefs.GetInt(“IsNewUser”) == 0)
{
agreementPopUp.Show();
}
else if (PlayerPrefs.GetInt(“IsNewUser”) == 2)
{
PlayerPrefs.SetInt(“IsNewUser”, 1);
PlayerPrefs.Save();
SetNickname();
}
}
else
{
SetNickname();
}
}
else
{
if (callback.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (callback.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
});
#endif
}
// 동기
else
{
Debug.Log(“동기 패더레이션 인증 진입”);
#if UNITY_ANDROID
Debug.Log(“Before GetToken”);
BackendReturnObject BRO = Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, “gpgs”);
Debug.Log(BRO);
#elif UNITY_IOS
Debug.Log(“Before GetToken”);
BackendReturnObject BRO = Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Apple, “siwa”);
Debug.Log(“After GetToken”);
Debug.Log(BRO);
#endif
if (BRO.IsSuccess())
SetNickname();
else
{
if (BRO.GetMessage().Contains(“blocked user”))
blockUserErrorPopUp.Show();
if (BRO.GetMessage().Contains(“Gone user”))
{
deletedPopUp.Show();
}
}
}
}
}
잘못된 부분이 있을까요