Firebase 비동기 작업에서 UI 업데이트 문제 해결

김보근·2024년 11월 1일

Unity

목록 보기
95/113

문제 발생 상황

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으로 작업을 제어하거나, 메인 스레드에서 실행되도록 관리하는 것이 중요하다.

profile
게임개발자꿈나무

0개의 댓글