Firebase를 이용해 로그인과 회원가입 기능을 구현하면서, 실패 시 이를 알리는 팝업창 UI가 화면에 표시되지 않는 문제가 발생했다. 로그 메시지는 정상적으로 출력되었지만, 팝업창이 활성화되지 않았다.
Firebase의 SignInWithEmailAndPasswordAsync 및 CreateUserWithEmailAndPasswordAsync는 비동기 작업이다. 이 비동기 메서드는 별도의 스레드에서 실행되기 때문에, 해당 작업이 완료된 후 UI 업데이트 코드가 실행될 때 Unity의 메인 스레드에서 UI 활성화 코드가 실행되지 않았다.
Unity의 UI 요소(게임 오브젝트 활성화/비활성화 포함)는 반드시 메인 스레드에서 실행되어야 하므로, 비동기 작업이 메인 스레드에서 실행되지 않을 경우 UI가 정상적으로 표시되지 않거나 무시되는 문제가 발생할 수 있다.
async와 await 키워드를 사용해 비동기 작업이 완료된 후 UI 업데이트가 메인 스레드에서 실행되도록 보장했다. await을 사용하면 비동기 작업이 완료된 뒤에도 메서드가 메인 스레드에서 계속 실행되기 때문에 UI 업데이트가 정상적으로 이루어진다.
구현코드
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
using TMPro;
using Firebase.Auth;
public class AuthManager : MonoBehaviour
{
[SerializeField] TMP_InputField emailField;
[SerializeField] TMP_InputField passwordField;
[SerializeField] GameObject authNotice;
private FirebaseAuth auth;
private WaitForSecondsRealtime wait;
private void Awake()
{
auth = FirebaseAuth.DefaultInstance;
wait = new WaitForSecondsRealtime(2);
}
public async void Login()
{
try
{
await auth.SignInWithEmailAndPasswordAsync(emailField.text, passwordField.text);
Debug.Log(emailField.text + " 로 로그인 하셨습니다.");
}
catch
{
StartCoroutine(ShowPopupRoutine(0)); // 0번 자식 (로그인 실패 팝업)
}
}
public async void Register()
{
try
{
await auth.CreateUserWithEmailAndPasswordAsync(emailField.text, passwordField.text);
Debug.Log(emailField.text + "로 회원가입 성공");
}
catch
{
StartCoroutine(ShowPopupRoutine(1)); // 1번 자식 (회원가입 실패 팝업)
}
}
IEnumerator ShowPopupRoutine(int childIndex)
{
// 적절한 팝업만 표시
authNotice.SetActive(true);
for (int i = 0; i < authNotice.transform.childCount; i++)
{
authNotice.transform.GetChild(i).gameObject.SetActive(i == childIndex);
}
yield return wait;
authNotice.SetActive(false);
}
}
async와 await 키워드를 사용하여 Firebase 비동기 작업이 완료된 후 메인 스레드에서 UI 업데이트가 실행되도록 했다.
실패 시 catch 블록에서 팝업을 활성화하는 코루틴 ShowPopupRoutine을 호출하여 해당 팝업을 2초 동안 표시한 후 자동으로 닫히도록 했다.
Unity의 UI 업데이트는 반드시 메인 스레드에서 실행되어야 한다는 점을 확인했다.
async/await를 사용해 비동기 작업이 완료된 후 메인 스레드에서 남은 작업을 안전하게 실행할 수 있다는 것을 배웠다.
비동기 작업 내에서 UI와 같은 Unity 요소를 변경할 때는 async/await으로 작업을 제어하거나, 메인 스레드에서 실행되도록 관리하는 것이 중요하다.
