[Unity/TIL] Firebase Cloud Functions - 서버에서 뽑기 로직 돌리기(2)
2025.05.19 - [프로젝트 일지/Unity] - [Unity/TIL] Firebase Cloud Functions - 서버에서 뽑기 로직 돌리기(1)
[Unity/TIL] Firebase Cloud Functions (1) - 함수 배포하기
프로젝트 '오집마'에서는 가챠 시스템이 존재한다. 그런데 가챠 로직을 클라에서 돌리고 있었는데, 이는 실제 출시하는 게임에서는 있을 수 없는 일이다! 그래서 우리도 Cloud Functions를 사용하여
ramenkirby.tistory.com
초기 세팅
FirebaseFunctions 인스턴스를 받아놓는다. 비동기함수이므로 functions 함수를 호출하는 시점과 비교/판단해서 적잘한 곳에서 초기화하면 된다.
FirebaseFunctions functions;
public void Init()
{
if (functions != null) return;
// Firebase 초기화
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
{
if (task.Result == DependencyStatus.Available)
{
functions = FirebaseFunctions.DefaultInstance;
IsReady = true;
Util.Log("Firebase 준비 완료!");
}
else
{
Util.LogError("Firebase 초기화 실패: " + task.Result.ToString());
}
});
}
호출
호출 후 결과를 받는 것도 비동기로 이루어지기 때문에 서버에서 받은 결과값으로 실행할 함수는 onResult Action으로 받아 실행시켜줬다.
public void CallGacha(int count, bool isUnit, Action<List<GachaResult>> onResult = null)
{
if (functions == null)
{
Init();
}
// Cloud Function에 넘길 데이터(callData) 준비하는 함수
SettingGradeRanges(count, isUnit);
functions.GetHttpsCallable("gachaDrawWithGuarantees")
.CallAsync(callData)
.ContinueWithOnMainThread(task =>
{
if (task.IsFaulted || task.IsCanceled)
{
Util.LogError("가챠 실패: " + task.Exception);
return;
}
// Data를 JSON 문자열로 변환 (바로 변환이 어려워서 이런 방식으로 결정)
string json = JsonConvert.SerializeObject(task.Result.Data);
// JSON 역직렬화
GachaResultWrapper parsed = JsonConvert.DeserializeObject<GachaResultWrapper>(json);
foreach (GachaResult r in parsed.results)
{
//Util.Log($"등급: {r.grade}, ID: {r.id}"); // 테스트용
}
onResult?.Invoke(parsed.results);
});
}
서버에서 계산되고 넘어온 데이터 task.Result.Data는 ~~때문에 저렇게 파싱했다.
functions에 데이터를 넘길 때 firebase에서 알아서 한 번 더 키-값으로 묶어서 보내지기 때문에 js에서 data를 바로 사용하면 안되고 data.data를 받아서 써야 한다. 처음에 이거를 몰라서 한참 헤맸다.
이런 구조로 데이터를 받게 된 이유는 아래 디버깅 과정에 담았다.
디버깅 과정
함수를 서버에 배포하는 것보다 오류 원인 찾고 해결하는 것이 어려웠다. js쓰는 것도 낯선데 디버깅이 번거로워!! 직접 콘솔로그를 찍어서 봤다.
firebase functions:log 명령어로 js에서 찍어둔 로그를 확인할 수 있다.
데이터를 무조건 Dictionary<string, object> 유형 바로 키-값 쌍으로 넣어줘야 해서 아래와 같은 모양새로 넣어주었다.
그런데 Log를 봤을 때 gradeRanges가 제대로 나오지 않는 모습이 보였다. drawCount도 100을 넣어 호출한건데 10이 나왔다. 아래 코드처럼 js에서 Number로 변환 실패하면 10으로 나오게한거라 로그를 보고 제대로 안들어갔음을 알 수 있었다...
🔽 잘못된 걸 확인했던 로그
gradeRanges는 undefined, drawCount는 10으로 찍힘
2025-05-19T05:56:22.152857Z W gachadrawwithguarantees:
2025-05-19T05:56:22.164751Z D gachadrawwithguarantees: {"verifications":{"app":"MISSING","auth":"MISSING"},"message":"Callable request verification passed"}
2025-05-19T05:56:22.164873Z ? gachadrawwithguarantees: gradeRanges: undefined
2025-05-19T05:56:22.164947Z ? gachadrawwithguarantees: drawCount: 10
디버깅해보면 서버에서 오는 Data가 results 키에 담겨오는 것을 알 수 있는데 (사진 참고)
Firebase SDK가 자동으로 data: {...} 로 감싸기 때문에 유니티에서 제대로 보냈어도 제대로 파싱이 안됐을 가능성을 예측할 수 있었다. 그래서 data.data로 사용하니 해결된 것임.
정리
1. 서버에 데이터를 보낼 때는 그대로 gradeRanges 키 - 값, gradeCount 키 - 값의 Dictionary 형태로 보낸다.
2. 서버에서는 받은 data에서 data를 한 번 더 꺼내서 사용한다. data.data
실사용 코드
서버 함수 호출하는 코드
호출할 때 넣어주는 데이터인 callData 준비하는 코드