GPGSV2 로그인 시 뒤끝 서버에 유저가 등록이 안됩니다

GPGSV2로 로그인 기능을 구현했습니다. 로그인은 잘 진행이 되는데 뒤끝 서버에 로그인한 유저가 등록이 안되고 있습니다. 구글 플레이 콘솔에 테스터 계정으로도 등록이 되어 있는 계정입니다.

using BackEnd;

using GooglePlayGames;

using GooglePlayGames.BasicApi;

using UnityEngine;

public class GoogleLogin : MonoBehaviour

{

void Awake()

{

    PlayGamesPlatform.DebugLogEnabled = true;

    PlayGamesPlatform.Activate();

}

void Start() {

  PlayGamesPlatform.Instance.Authenticate(ProcessAuthentication);

}

void ProcessAuthentication(SignInStatus status) {

  if (status == SignInStatus.Success) {

    GetAccessCode();

    // Continue with Play Games Services

  } else {

    // Disable your integration with Play Games Services or show a login button

    // to ask users to sign-in. Clicking it should call

    // PlayGamesPlatform.Instance.ManuallyAuthenticate(ProcessAuthentication).

  }

}

public void GetAccessCode()

{

  PlayGamesPlatform.Instance.RequestServerSideAccess(

    /* forceRefreshToken= */ false,

    code => {

      Debug.Log("구글 인증 코드 : " + code);

        code = "4/0AeaYSHCuDcNr-Kai7Hx42BpreFACh3wLVEe5u7ZF-phOY8qv6lAHQ2R7a5Y3zWOqkfqocw";

      Backend.BMember.GetGPGS2AccessToken(code, googleCallback =>

      {

        Debug.Log("GetGPGS2AccessToken 함수 호출 결과 " + googleCallback);

        string accessToken = googleCallback.GetReturnValuetoJSON()["access_token"].ToString();

        if (googleCallback.IsSuccess())

        {

          accessToken = googleCallback.GetReturnValuetoJSON()["access_token"].ToString();

        }

        Backend.BMember.AuthorizeFederation(accessToken, FederationType.GPGS2, callback =>

        {

            Debug.Log("뒤끝 로그인 성공했습니다. " + callback);

            GameData.getInstance().LoadUserData();

        });

      });

    });

}

}
이건 전체코드이고 아래는 로그캣으로 로그를 확인했을 때 나오는 오류 메세지 입니다.
GetGPGS2AccessToken 함수 호출 결과 StatusCode : 400
09-01 08:28:48.413 5710 5738 I Unity : ErrorCode : GoogleOAuthException
09-01 08:28:48.413 5710 5738 I Unity : Message : Object reference not set to an instance of an object.
09-01 08:28:48.413 5710 5738 I Unity : <>c:b__3_1(BackendReturnObject)
09-01 08:28:48.413 5710 5738 I Unity : or7e3bc9vuCj8lKipEw.d__8:MoveNext()
09-01 08:28:48.413 5710 5738 I Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-01 08:28:48.413 5710 5738 I Unity :
09-01 08:28:48.429 5710 5738 E Unity : NullReferenceException: Object reference not set to an instance of an object.

  • 뒤끝 SDK 버전 : 5.18.1
  • 프로젝트명 : ZombieAlive
  • 스테이터스 코드 :
  • 에러 코드 :
  • 에러 메시지 :

안녕하세요 개발자님,
관련 내용 확인하여 안내드릴 수 있도록 하겠습니다.

보내주신 코드를 확인한 결과, 구글 인증 code를 하드코딩하여 사용하고 계신 것으로 보입니다.
인증 코드를 하드코딩할 경우 코드의 유효기간 만료로 인해 말씀해주신 것과 같은 GoogleOAuthException 오류가 발생할 수 있습니다. 따라서 로그인 시마다 새로운 인증 코드를 발급받아 사용하도록 구성해 주시기 바랍니다.

또한 GetGPGS2AccessToken 함수 호출 이후 응답의 성공/실패 여부를 확인하지 않고 바로 사용하고 계신 것으로 확인됩니다.
현재 코드에서

string accessToken = googleCallback.GetReturnValuetoJSON()["access_token"].ToString();

와 같이 접근할 경우, 응답이 실패했을 때 NullReferenceException이 발생할 수 있습니다. 반드시 응답 성공 여부를 확인한 뒤에만 access token을 사용해 주시기 바랍니다.

AuthorizeFederation 함수 또한 동일하게, 응답이 성공한 경우에만 호출하도록 수정해 주시길 권장드립니다.

말씀해주신대로 진행하니 같은 오류는 발생하지 않고 있습니다. 그런데 새 오류가 두가지 발생했습니다.
뒤끝 로그인 성공했습니다. StatusCode : 400
09-03 13:17:26.738 3958 3990 I Unity : ErrorCode : UndefinedParameterException
09-03 13:17:26.738 3958 3990 I Unity : Message : undefined google_hash, google_hash을(를) 확인할 수 없습니다
09-03 13:17:26.738 3958 3990 I Unity : <>c:b__3_2(BackendReturnObject)
09-03 13:17:26.738 3958 3990 I Unity : or7e3bc9vuCj8lKipEw.d__5`1:MoveNext()
09-03 13:17:26.738 3958 3990 I Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-03 13:17:26.738 3958 3990 I Unity :
09-03 13:17:26.766 3958 3990 E Unity : :x: GameData 불러오기 실패 : StatusCode : 400
09-03 13:17:26.766 3958 3990 E Unity : ErrorCode : BadRequestException
09-03 13:17:26.766 3958 3990 E Unity : Message : Login is yet
09-03 13:17:26.766 3958 3990 E Unity : GameData:b__39_0(BackendReturnObject)
09-03 13:17:26.766 3958 3990 E Unity : BackEnd.Functions.d__12:MoveNext()
09-03 13:17:26.766 3958 3990 E Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-03 13:17:26.766 3958 3990 E Unity :

이런 오류가 발생하였고, 여전히 뒤끝 서버에는 유저가 등록되지 않고 있습니다.

public void LoadUserData()
{
    // Backend.GameData.GetMyData에 콜백 함수를 추가
    // bro는 서버로부터 받은 응답 객체
    Backend.GameData.GetMyData("USER_GAME_DATA", new Where(), 1, (bro) =>
    {
        if (bro.IsSuccess())
        {
            if (bro.Rows().Count > 0)
            {
                // 데이터가 있을 경우
                var row = bro.Rows()[0];
                inDateValue = row["inDate"]["S"].ToString();

                if (row.ContainsKey("rowId"))
                    rowId = row["rowId"]["S"].ToString();
                else
                {
                    rowId = System.Guid.NewGuid().ToString();

                    Param fixParam = new Param();
                    fixParam.Add("rowId", rowId);

                    Where where = new Where();
                    where.Equal("inDate", inDateValue);

                    // ✅ Update도 비동기 콜백으로 처리
                    Backend.GameData.Update("USER_GAME_DATA", where, fixParam, (updateBro) =>
                    {
                        if (updateBro.IsSuccess())
                        {
                            Debug.Log("rowId 업데이트 성공");
                        }
                        else
                        {
                            Debug.LogError("rowId 업데이트 실패: " + updateBro);
                        }
                    });
                }

                cLevel = int.Parse(row["cLevel"]["N"].ToString());
                cChap = int.Parse(row["cChap"]["N"].ToString());

                if (row.ContainsKey("itemsTriggered"))
                {
                    string json = row["itemsTriggered"]["S"].ToString();
                    itemsTriggered = JsonMapper.ToObject<List<bool>>(json);
                }

                if (row.ContainsKey("levelScore"))
                {
                    string jsonScore = row["levelScore"]["S"].ToString();
                    levelScore = JsonMapper.ToObject<List<int>>(jsonScore);
                }

                if (row.ContainsKey("levelStar"))
                {
                    string jsonStar = row["levelStar"]["S"].ToString();
                    levelStar = JsonMapper.ToObject<List<int>>(jsonStar);
                }

                Debug.Log("✅ GameData 불러오기 성공");
            }
            else
            {
                // 데이터가 없을 경우 새로 생성
                ClearPlayerPrefsForNewUser();

                rowId = System.Guid.NewGuid().ToString();
                cLevel = 0;
                cChap = 0;
                itemsTriggered = new List<bool>(new bool[15]);
                levelScore = new List<int>();
                levelStar = new List<int>(new int[totalLevel]);

                Debug.Log("기존 GameData가 없어 새로 생성합니다.");

                Param param = new Param();
                param.Add("cLevel", cLevel);
                param.Add("cChap", cChap);
                param.Add("rowId", rowId);

                string jsonItems = JsonMapper.ToJson(itemsTriggered);
                param.Add("itemsTriggered", jsonItems);

                string jsonScore = JsonMapper.ToJson(levelScore);
                param.Add("levelScore", jsonScore);

                string jsonStar = JsonMapper.ToJson(levelStar);
                param.Add("levelStar", jsonStar);

                // ✅ Insert도 비동기 콜백으로 처리
                Backend.GameData.Insert("USER_GAME_DATA", param, (insertBro) =>
                {
                    if (insertBro.IsSuccess())
                    {
                        Debug.Log("✅ GameData 기본 row 생성 성공");
                        // 생성 후 데이터를 다시 저장
                        SaveUserData();
                    }
                    else
                    {
                        Debug.LogError("❌ GameData 기본 row 생성 실패 : " + insertBro);
                    }
                });
            }

            // PlayerPrefs 내 levelStar 데이터 마이그레이션
            for (int i = 1; i <= totalLevel; i++)
            {
                string key = "levelStar_" + i;
                if (PlayerPrefs.HasKey(key))
                {
                    int starCount = PlayerPrefs.GetInt(key);
                    if (i - 1 < levelStar.Count && levelStar[i - 1] < starCount)
                    {
                        levelStar[i - 1] = starCount;
                        Debug.Log($"레벨 {i} 별 {starCount}");
                    }
                }
            }

            PlayerPrefs.SetInt("cLevel", cLevel);
            PlayerPrefs.SetInt("cChap", cChap);
        }
        else
        {
            Debug.LogError("❌ GameData 불러오기 실패 : " + bro);
        }
    });
}

오류 중 LoadUserData 오류 관련 함수 코드 첨부하겠습니다.
또 구글 해시키를 발급받았는데 왜 해시키가 없다는 오류가 발생하였는지 궁금합니다.

회원가입/로그인 과정에서 해시키 오류가 발생한 것으로 확인되며,
이로인해 후속으로 이어지는 유저 데이터 조회 또한 Login is yet 에러가 발생한 것입니다.

에러 발생 호출 이력을 확인 시 해시키가 빈값으로 전송되어오고 있습니다.
프로가드를 사용하시는 경우 아래의 예외 적용이 이루어져 있는지 확인 후 재시도 바랍니다.

-keep class io.thebackend.unity.** {*;}
-keep class io.thebackend.googlelogin.* {*;}
-keep class io.thebackend.googlelogin.GoogleLogin {*;}
-keep class io.thebackend.googlelogin.BackendGoogleLoginCallback {*;}
-keep class io.thebackend.googlelogin.BackendOnUnityCallback {*;}