GPGS로그인을 통한 뒤끝 유저정보 생성이 안되는데 도와주세요.

안녕하세요. 뒤끝 문서를 보면서, 게임 실행 시, 구글로그인이 되도록 하였습니다.

구글로그인 성공은 되나, 뒤끝 콘솔 - 게임유저관리에 유저 정보가 생성되질 않습니다.

작동 순서

  1. 게임 실행 시, GPGSManager에서, GPGS로그인 & 뒤끝 로그인

// Include GPGS namespace
using GooglePlayGames;
using GooglePlayGames.BasicApi;
using UnityEngine.SocialPlatforms;
// Include Backend
using BackEnd;
using UnityEngine;

public class GPGSManager : MonoBehaviour
{
public static GPGSManager instance;

private void Awake()
{
    if (instance == null)
    {
        instance = this;
        DontDestroyOnLoad(gameObject);
    }
    else
        Destroy(gameObject);
}

// custome GPGS set and activate
void Start()
{
    PlayGamesClientConfiguration config = new PlayGamesClientConfiguration
        .Builder()
        .RequestServerAuthCode(false)
        .RequestEmail()
        .RequestIdToken()
        .Build();
    //커스텀된 정보로 GPGS 초기화
    PlayGamesPlatform.InitializeInstance(config);
    PlayGamesPlatform.DebugLogEnabled = true;
    //GPGS 시작.
    PlayGamesPlatform.Activate();

    GPGSLogin();
}

// GPGS 로그인 
public void GPGSLogin()
{
    // 이미 로그인 된 경우
    if (Social.localUser.authenticated == true)
    {
        BackendReturnObject BRO = Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, "gpgs");
    }
    else
    {
        Social.localUser.Authenticate((bool success) => {
            if (success)
            {
                // 로그인 성공 -> 뒤끝 서버에 획득한 구글 토큰으로 가입요청
                BackendReturnObject BRO = Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, "gpgs");
                
                Backend.BMember.UpdateFederationEmail(GetTokens(), FederationType.Google);
                Backend.BMember.CheckUserInBackend(GetTokens(), FederationType.Google);

                
            }
            else
            {
                // 로그인 실패
                Debug.Log("Login failed for some reason");
            }
        });
    }

    Backend.BMember.LoginWithTheBackendToken((callback) =>
    {
        if (callback.IsSuccess())
        {
            Debug.Log("자동 로그인에 성공했습니다");
        }
    });
}

// 구글 토큰 받아옴
public string GetTokens()
{
    if (PlayGamesPlatform.Instance.localUser.authenticated)
    {
        // 유저 토큰 받기 첫번째 방법
        string _IDtoken = PlayGamesPlatform.Instance.GetIdToken();
        Debug.Log("나의 토근 :" + _IDtoken);
        // 두번째 방법
        // string _IDtoken = ((PlayGamesLocalUser)Social.localUser).GetIdToken();
        return _IDtoken;
    }
    else
    {
        Debug.Log("접속되어있지 않습니다. PlayGamesPlatform.Instance.localUser.authenticated :  fail");
        return null;
    }
}

public void OnClickLogin()
{
    Backend.BMember.AuthorizeFederation("federationToken", FederationType.Google, "GPGS로 가입함");
}

}

Backend.BMember.LoginWithTheBackendToken((callback) =>
{
if (callback.IsSuccess())
{
Debug.Log(“자동 로그인에 성공했습니다”);
}
}); < 이거 하면 되는거아닌가요?

방안을 제시해주면 정말 감사하겠습니다. 하루내내 해봤는데 제자리걸음이네요.

GetToken()에서 토근값도 찍힙니다.

좋아요 1

안녕하세요 개발자님.

Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, “gpgs”); 해당 함수를 호출했을 때 리턴되는 에러코드를 알려주시면 감사하겠습니다.

또한
Backend.BMember.LoginWithTheBackendToken() 해당 함수는 이전에 뒤끝으로 로그인한 적이 있을경우, 기기에 저장된 리프레시토큰을 이용해서 로그인 하는 함수입니다. 자동로그인하는 기능이라 이해하시면 될 것 같습니다.

따라서 Backend.BMember.AuthorizeFederation()(페데레이션으로 로그인)를 호출한 후에는 Backend.BMember.LoginWithTheBackendToken()(저장된 토큰으로 로그인)를 호출하지 않으셔도 됩니다.

에디터에서 로그인했을 떄는, Login failed for some reason 이렇게 표시되고,

로그캣으로 로그를찍어보니, 로그가 찍히진않습니다,

GetTokens에서 토큰정보만 로그캣에 나오네요,

04-27 22:45:09.825 28894 3344 I Unity : 나의 토근 :eyJhbGciOiJSUzI1NiIsImtpZCI6Ijc3MjA5MTA0Y2NkODkwYTVhZWRkNjczM2UwMjUyZjU0ZTg4MmYxM2MiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI5MzUwNzkyOTQ1MjctMzRkcDdrajBzanY0cGY3YmFqcmU5Nzg0ODNoZzFmaG0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI5MzUwNzkyOTQ1MjctcmExcmpvZTI3bDc0MDkzcm8ybDZrZzdodmZpa3FodGUuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDA5OTczODU5ODA1MjYwNjMxNTQiLCJlbWFpbCI6ImNoZmhkZGwyNzc4QGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJpYXQiOjE2MTk1MzA1NDgsImV4cCI6MTYxOTUzNDE0OH0.tmB01Z58kdJOWTm8vZgHbMQjMeJ40FinpKX8FwKz8G5y8eYCAlsg2iy5T95tCSnYDsBPpvtOF5oCCZw0PkykbLIe7cPpt6G-dLHJkn0h_rWr_fvuGkPlf1z9HhOTAOtucyQddL72KdA2tSro7iYP7Lvkz9nnW2Jitcr_q2aErSX8pKxFex2RAq2g52GfpDD-yr4rBJuZovyDWDHrMj9oIyQZL9aW3W2lEDkuM_bwRqs0-DFjFuxwHR0uxEU2DJ5ur-EJfY4Kn1CGLm9dDD7zaETxYsD_zP0tx4A312-KAJU5ETwOxVwlcYC24lFOq18qzllTgXICEnZ0KTKGzvVQjQ

로그인을 하게되면, 유저정보에 입력되게하려면 어떻게해야하나요? 아니면 좋은 영상같은게없을까요?

GPGS 플러그인은 안드로이드 전용이기 때문에 에디터에서 테스트가 불가능하며 해당 에러가 발생하게 됩니다.

로그를 확인해본 결과, 뒤끝 함수 호출 시에 다음과 같은 에러가 리턴되는 것으로 확인이되는데 이와 관련하여 구글 해시키가 제대로 입력되어있는지, 그리고 패키지 네임이 등록한 프로젝트에 있는 정보와 동일한지 확인해주시면 감사하겠습니다.

4월 27일 새벽 11시 45분경
401
BadUnauthorizedException
bad packageName, 잘못된 packageName 입니다

4월 26일 새벽 11시 45분경
401
BadUnauthorizedException
bad google_hash, 잘못된 google_hash 입니다

안녕하세요 Hassan님. 답변 정말 감사합니다.

이 날 이후로, 시간내서 계속 해보고있습니다.

현재, 해쉬키 릴리즈, 디버그버전 얻어서 입력했고,

2가지 궁금한점이 있습니다.

  1. 커스텀 회원가입이 에디터에서는 잘되는데, 핸드폰기기에서는 “아이디 또는 비밀번호가 틀렸습니다” 라고 출력됩니다.

회원가입 코드를 입력했는데 이러네요…

  1. 구글로그인이 성공 되었는데, 뒤끝콘솔 유저정보에 계정생성이 되지않는데 따로 추가를해야할 것이있을까요?

=
// 구글에 로그인하기
private void GoogleAuth()
{
if (PlayGamesPlatform.Instance.localUser.authenticated == false)
{
Social.localUser.Authenticate(success =>
{
if (success == false)
{
Debug.Log(“구글 로그인 실패”);
return;
}

            // 로그인이 성공되었습니다.
            Debug.Log("GetIdToken - " + PlayGamesPlatform.Instance.GetIdToken());
            Debug.Log("Email - " + ((PlayGamesLocalUser)Social.localUser).Email);
            Debug.Log("GoogleId - " + Social.localUser.id);
            Debug.Log("UserName - " + Social.localUser.userName);
            Debug.Log("UserName - " + PlayGamesPlatform.Instance.GetUserDisplayName());
        });
    }
}
// 구글 토큰 받아오기
private string GetTokens()
{
    if (PlayGamesPlatform.Instance.localUser.authenticated)
    {
        // 유저 토큰 받기 첫번째 방법
        string _IDtoken = PlayGamesPlatform.Instance.GetIdToken();
        // 두번째 방법
        // string _IDtoken = ((PlayGamesLocalUser)Social.localUser).GetIdToken();
        return _IDtoken;
    }
    else
    {
        Debug.Log("접속되어있지 않습니다. 잠시 후 다시 시도하세요.");
        GoogleAuth();
        return null;
    }
}

// 구글토큰으로 뒤끝서버 로그인하기 - 동기 방식
public void OnClickGPGSLogin()
{
    BackendReturnObject BRO = Backend.BMember.AuthorizeFederation(GetTokens(), FederationType.Google, "gpgs로 만든계정");
    if (BRO.IsSuccess())
    {
        Debug.Log("구글 토큰으로 뒤끝서버 로그인 성공 - 동기 방식-");
    }
    else
    {
        switch (BRO.GetStatusCode())
        {
            case "200":
                Debug.Log("이미 회원가입된 회원");
                break;

            case "403":
                Debug.Log("차단된 사용자 입니다. 차단 사유 : " + BRO.GetErrorCode());
                break;
        }
    }
}

=

저도 비슷한일이있었는데 정확하진않지만
스토어인증정보 넣고
구글토큰 두번째방법 이용하더니 해결됐습니다.

유저 토큰 받기 첫번째 방법
// string _IDtoken = PlayGamesPlatform.Instance.GetIdToken();

이걸 슬래시로 막으시고 두번째방법 슬래시를 열어서 한번 해결해보세용
// 두번째 방법
string _IDtoken = ((PlayGamesLocalUser)Social.localUser).GetIdToken();
return _IDtoken;

좋아요 1

안녕하세요 개발자님

로그를 확인해본 결과, 로그인 시에 다음과 같은 에러가 반환이 되고 있습니다.
Error: bad google_hash, 잘못된 google_hash 입니다

해당 에러는 앱을 키스토어를 이용하여 구글 스토어에 등록할때 발급된 릴리즈키나 디버그 키가 뒤끝 콘솔에 잘못 입력되어있을 경우에 발생합니다.

등록한 디버그 혹은 릴리즈키에 공백이 있거나 잘못 입력되어있을 경우, 키스토어가 등록안된체로 앱이 빌드되었을 경우 해당 에러가 발생할 수 있으니 이부분 확인 부탁드립니다.

구글 해시는 Debug.Log(Backend.Utils.GetGoogleHash()); 해당 코드를 통해서도 확인 할 수 있으니 해당 함수를 호출하여 해시키를 확인하는 것도 추천드립니다.

릴리즈 키에 공백이 있어서 에러가 났었네요. 해결하였습니다.

현재, 게임을 실행하면, 상단에 구글로그인이 되었다고 나오는데, 이 때, 자동으로 뒤끝서버에 로그인 정보를 보내야 하나요? 매번 접속할 떄마다.
아래 사진은, 버튼 누르면, 구글로그인 정보를 뒤끝에 보내서, 유저정보가 생기는 거인데, 이걸 게임 접속할떄마다 매번 자동으로 불리게 해야하는건가요?? 어떤방식으로해야 안전한지 궁금합니다.

답변감사합니다. 구글토큰정보는 첫번째 방식으로도 잘 가져오고 있어요 ㅠㅠ 다른문제인거같아요

안녕하세요 개발자님 :slight_smile:
Google 로그인과, 뒤끝 로그인은 별개로 이루어지게 되어있습니다.
Google 로그인 후, 뒤끝 로그인을 진행해 주셔야 게임을 원활하게 이용이 가능하오니
이점 참고하시어 이용에 불편 없으시기 바랍니다.

답변 감사합니다. ㅎㅎ

  1. 뒤끝서버 구글로그인 실패 시, 게임 못들어가게 검사를 하려고하는데,
    게임씬에 입장하기 전, 뒤끝서버에 로그인이 되었는지 검사하는 함수가 있을까요?

  2. 로그인 하면, 유저에 관한테이블을 넣어주려는데, 로그인할 때, 해당 유저테이블이 있는지 없는지 검사하는 함수가
    있을까요??
    ex) 로그인 시, "user"라는 테이블을 가지고 있는지 검사할때,
    Backend.GameData.GetMyData(“user”, new Where(), 1); 이렇게 찾는거인지… 레퍼런스가 보이질않네요ㅠ

  3. Get() or GetMyData()를 사용해서 Table을 받아오려면, indate를 입력하라뜨는데요.
    Insert()를통해, Indate 구해서, 어디에 따로 저장해서 사용하는거인가요??

  4. 게임에서, 읽기전용 데이터들 (상점에서 파는 아이템 데이터) 같은 경우는, 서버테이블이아닌, “차트” 라는 곳에서 관리해서 쓰는건지 궁금합니다. CDN같은용도인지 궁금합니다.

  5. 만약 차트에서 읽기전용 데이터들을 사용하는거라면, 해커가 데이터해킹해서 S급무기 7만원인거를 0원으로 바꿔서 산다면, 서버검증도 같이 이루어지는건가용?

위 방식보다 더 좋은방법이 있다면, 조언 부탁드리겠습니다.
질문이많아서 죄송합니다.

안녕하세요 개발자님

순서대로 답변해두르곘습니다.

  1. 로그인이 되지 않은 상태로 뒤끝 함수를 사용하면 Exception과 함께 함수호출이 불가능합니다.
    별도의 검사하는 함수는 없으나 구글 로그인 이후 페데레이션 로그인 하여 성공/실패 여부에 따라 게임을 진행/다시 로그인 시도를 시키면 될 거 같습니다.

  2. 네 개발자님이 말씀하신 대로 user 테이블에 데이터가 있는지 확인하려면 데이터를 읽어오기 함수 호출 후 rows에 반환되는 값이 있는지 확인해주시면 될 거 같습니다.

  3. inDate는 여러번 같은 데이터를 사용해야 할 경우, 최초 1회 where문을 통해서 데이터를 읽어옴 -> 읽어온 데이터에서 inDate를 로컬 변수 저장 -> 이후 데이터 수정 시 where문이 아닌 inDate를 이용하여 수정
    등으로 where문보다 더 쉽게 특정 데이터를 수정할 수 있습니다.

  4. 모든 유저들이 공통적으로 읽어올 데이터는 차트에 저장하여 쉽게 읽어올 수 있습니다.
    또한 해당 데이터들이 변경될 경우에는 콘솔에서 차트를 변경하여 쉽게 수정 가능합니다.
    차트에 상점 아이템 혹은 캐시 아이템 리스트를 저장하고 콘솔에서 원할 때 아이템의 설명 또는 가격 수정, 아이템 추가 기능으로 활용할수 있습니다.

  5. 뒤끝은 차트의 데이터를 읽어오기만 할뿐 이후 별도의 서버검증은 이루어지지 않습니다.

  1. GPGS 로그인해서, 게임접속전에 gpgs 실패인지 검사하는 함수가 따로 있을까요??
    => GPGS 로그인 못하면, 재로그인 시도 하게 만드려고합니다.

  2. user테이블이 있는지 row 반환되는지 검사하는 함수좀 알고싶습니다. HasFirstKey()로하니, 2번되고 그이후에 되네요…

  3. 인데이트는 유니티 내 PlayerPrefs에서 저장해서 주로사용 되나요?

  4. 차트에, 상점에 판매되는 아이템의 Cash(유료 재화)가 적히게되고, 유저가 이 Cash로 아이템을 사게되는데,
    아이템 판매하는 캐시 가격을 0으로 변조하고 구매하게되면, 서버검증은없으니, 해킹이 되는건가요??

  5. 차트는 그럼, CDN의 역할을 하는거인가요? 게임업데이트 없이, 값 변경으로 데이터변경이되니.

안녕하세요 개발자님

차례대로 답변드리겠습니다.

1.

뒤끝 로그인 종류 관계없이 로그인에 실패하는 경우 로그인 실패가 반환되고 이 때 재로그인을 시도하도록 하시면 될 것 같습니다.

로그인 실패에 대해서는 개발자문서를 참고해주세요.

GPGS 로그인 자체를 실패하는 경우에는 GPGS 깃 허브 페이지를 참고해서 분기처리를 하시면 될 것 같습니다.

2.

별도로 검사하는 함수는 존재하지 않습니다.

user 테이블이 존재하지 않을 때 Backend.GameData.Get("user", new Where()); 와 같은 Get 함수를 호출하시면 아래와 같이 rows 에 빈 배열이 리턴이 되게 됩니다.

statusCode : 200
message : Success
returnValue : {"serverTime":"2021-03-23T07:07:01.235Z","rows":[],"firstKey":null}

자세한 설명은 Get 함수 개발자문서의 ReturnCase를 참고해주세요.

row 혹은 rows 가 반환되는지 확인하실 때는

rows 의 경우 HasRows() 함수를 통해 확인이 가능하시고,

row의 경우 아래와 같은 방법으로 확인하실 수 있습니다.

var bro = Backend.GameData.Get("user", new Where());
var json = bro.GetReturnValuetoJSON();
if(json.Keys.Contains("row"))
{
    // 처리
}

3.

뒤끝 SDK에서는 별도로 inDate를 로컬에 저장하지 않습니다.

inDate를 PlayerPrefs 등을 이용하여 로컬에 저장하여 사용하셔도 되고,

inDate만 별도의 테이블에 따로 저장하셔서 사용하셔도 됩니다.

이 부분은 개발자님의 재량에 따라 원하시는 데로 사용하셔도 무방할 것 같습니다.

다만 로컬에 저장하는 것은 위변조 되거나 혹은 클라이언트에서 다른 아이디로 로그인 했을 때의 문제 등이 발생할 수 있기 때문에 추천드리지는 않습니다.

4.

말씀하신 방법으로 사용하시는 경우 별도의 서버검증이 없으니 해킹의 위험이 있을 수 있습니다.

서버 검증이 필요하신 경우 뒤끝 펑션을 사용하셔서 아이템 구매 로직을 작성하시거나

혹은

TBC 기능을 사용하시면 됩니다.

5.

게임 업데이트 없이 차트 수정만으로 게임의 데이터 변경은 가능하지만,

뒤끝 차트에서는 CDN 과는 성격이 조금 다른 것 같습니다.

  1. 제가 Table을 Insert할 떄, Indate를 로컬에 저장해서 사용하려고하는 이유는,

방치형 게임에서, 몬스터를 잡으면, 골드가 500 획득한다할 때,

이 때, user테이블에서 gold를 500 더하려고 합니다.
그럼 업데이트하는 UpdateWithCalculation()에서,
파라미터로 테이블의 Indate를 요구하는데,

로컬에 따로 저장해서 쓰는방법말고, 뒤끝에서 추천하는 방법이있나요?

Insert할 때, 로컬에 저장안하면, 불러오는 방법이 생각이나질않네요.

안녕하세요 개발자님

게임 시작 시 해당 유저가 게임에서 사용하는 모든 테이블을 Get 하여

해당 테이블이 존재하지 않을 시 insert 하고,

테이블이 존재할 경우 해당 테이블의 inDate를 모두 메모리 상에 저장해두면

말씀하신 로직과 유사하게 이용이 가능할 것 같습니다.

아. 제가 말한 user 테이블은, 유저가 가지고있는 user테이블 말한거였어요.

찾아보니 GetMyData로 찾을수 있는거같네요.

이거로, 굳이 Indate 저장안하고 GetMyData().GetIndate()로 해당 유저의 테이블의 Indate를 사용하란말씀이시죠?

GetInDate 함수의 경우 리턴값에 제일 상단의 키값이 inDate가 있을 때 inDate 를 리턴하는 함수로,

Backend.GameData.Insert 의 리턴값에서만 사용할 수 있습니다.

Backend.GameData.GetMyData 함수를 사용하시는 경우에는 아래와 같이 사용하시면 inDate를 Get 할 수 있습니다.

var bro = Backend.GameData.GetMyData("tableName", new Where(), 1);
if(bro.IsSuccess() == false)
{
    return;
}

// 리턴값 처리 (https://developer.thebackend.io/unity3d/guide/BackendReturnObject/Flatten/)
var json = bro.FlattenRows();
// 데이터 내 inDate 확인
var inDate = json[0]["inDate"].ToString();

아래 개발자문서도 참고 부탁드립니다.

안녕하세요. 담당자님. 질문이 있습니다.

위 사진처럼, user 테이블에 stageId를 수정 하는데요.

  1. 비동기 callback => {(여기) }); (여기)에 Debug.Log를 삽입하였는데, 출력이 되질 않습니다.
    저 .Update()가 끝나고 불리는 callback이아닌가요?

  2. 데이터를 Update나 Insert할때 등, Param이 클래스다보니 계속 메모리를 할당하는데,
    효율적이게 사용하는 방법이없을까요? 방치형게임이다보니 계속 호출되서 문제가 발생할 것같아서 조언을 얻고싶습니다.

  3. 방치형 게임 제작중입니다. 거이 1초마다 몬스터 1마리를 죽이게 되서, 계속 "user"테이블을 UpdateWithCalculation()을 통해, 게임머니를 ++ 하고있는데요. 이렇게 사용하게되면 DB요금이 많이나오나요…? 다른 방법이있을까요??