| 작업 목표 📋
커스텀 에디터를 통해 보다 편하게 토픽 데이터를 생성하고, 픽셀 아트 데이터를 추가하는 기능들을 만들었으니, 이제 Firestore에 업로드된 데이터를 활용해 클라이언트에서 실제로 새로 추가된 데이터, 아직 다운로드되지 않은 데이터를 체크하여 팝업을 통해 원하는 토픽 데이터를 다운로드하게 기능을 구현하는 것이 목표입니다.
| TO DO LIST 💡
- Firestore 데이터 업데이트 체크 후 필요한 토픽 데이터 다운로드
- 추가된 토픽 데이터, 미 다운로드 토픽 데이터 체크
- 다운로드 기능 구현
- UI 구성 및 추가
- 기존 더미 데이터 플레이 로직 수정
| 작업 과정 🖥️
이미 기능들은 이전에 대부분 구현해 두어서 업데이트 관련 기능 구현과 기존 씬 구조 수정과 더미 데이터로 임시 더미 데이터를 이용한 플레이 로직을 수정하는 작업 위주로 진행했습니다.
| 업데이트 체크 기능 구현 방식
업데이트를 담당할 UpdateManager를 추가해 주었습니다.
로그인이 성공적으로 진행된 후 메인씬에 진입을 하게 되면 자동으로 추가된 토픽 데이터가 있는지 Firestore에 데이터들을 체크하게 구현하였습니다.
이 과정에서 토픽 데이터가 Firestore에 늘어나게 될 경우, 모든 데이터를 유저가 다운로드하게 한다면 Firestore의 부하와 유저의 용량 부분에서도 좋지 않다고 판단되어서 모두의 마블의 맵 다운로드처럼 원하는 데이터만 다운로드하도록 구현하였습니다.
| 추가된 토픽 데이터, 미 다운로드 토픽 데이터 체크
우선 현재 구현한 방법은 현재 Firestore에서 추가된 데이터들의 ID값과 현재 로컬의 저장된 ID값을 비교하여 차이나는 부분을 체크는 방식으로 구현하였습니다.
추후 더 나은 방식으로 수정할 예정입니다.
public event Action<bool> OnUpdateCheckCompleted
public Task CheckForUpdated()
{
// 로컬에 저장되어 있는 토픽 데이터 ID 리스트
List<string> localTopicDataIDs = DataManager.Instance.userData.LocalTopicDataIDs;
// 다운로드 하지 않은 토픽 데이터 리스트
List<TopicData> missingDataList = new List<TopicData>();
// 추가된 토픽 데이터 리스트
List<TopicData> outdatedDataList = new List<TopicData>();
// 토컬 ID 리스트가 비었거나, 추가된 ID가 없는 경우
if (localTopicDataIDs == null || localTopicDataIDs.Count == 0)
{
// Firestore에서 로드한 데이터를 missingDataList에 추가
foreach (var topicData in _topicDataList)
{
missingDataList.Add(topicData);
}
}
else
{
// 다운로드 하지 않은 토픽 데이터 ID 리스트
List<string> missingDataIDs = _topicDataList.Select(data => data.ID).Except(localTopicDataIDs).ToList();
// 미 다운로드 ID에 해당하는 Firestore 데이터를 missingDataList에 추가
foreach (var id in missingDataIDs)
{
TopicData serverData = _topicDataList.Find(data => data.ID == id);
if (serverData != null)
{
missingDataList.Add(serverData);
}
}
// Firestore 데이터와 비교하여 로컬에 없는 데이터를 outdatedDataList 추가
foreach (var id in localTopicDataIDs)
{
TopicData localData = DataManager.LoadJsonData<TopicData>(DataPath.GalleryDataPath, id);
TopicData serverData = _topicDataList.Find(data => data.ID == id);
if (serverData.LastUpdated > localData.LastUpdated)
{
outdatedDataList.Add(serverData);
}
}
}
// 각 DataList에 데이터들이 존재 할 경우 UpdatePopup을 화면에 띄움
bool updatedPopupShow = missingDataList.Count > 0 || outdatedDataList.Count > 0;
if (updatedPopupShow)
{
updatePopup.Show(outdatedDataList, missingDataList);
}
else
{
PopupManager.Instance.ShowPopup("업데이트 체크 완료", "모든 데이터가 추가되어 있습니다");
}
// 업데이트 체크 완료 이벤트 실행
OnUpdateCheckCompleted?.Invoke(updatedPopupShow);
return Task.CompletedTask;
}
| 다운로드 기능 구현
데이터를 체크하는 단계에서 추가, 미 다운로드한 데이터들의 ID값을 구해 놓았으므로, 해당하는 ID를 기존에 구현한 다운로드 메서드를 통해 로컬에 저장하게 구현하였습니다.
// 다운로드가 완료 되었을 때 이벤트
public event Action OnDownloadCompleted;
// 다운로드가 실패 했을 때 이벤트
public event Action<Exception> OnDownloadFailed;
public async Task DownloadTopicData(string topicID)
{
TopicData serverData = _topicDataList.Find(data => data.ID == topicID);
try
{
if (serverData != null)
{
string jsonData = JsonConvert.SerializeObject(serverData);
DataManager.SaveJsonData(DataPath.GalleryDataPath, topicID, jsonData);
DataManager.Instance.userData.LocalTopicDataIDs.Add(topicID);
DataManager.Instance.userData.LastUpdated = DateTime.Now;
#if UNITY_ANDROID && !UNITY_EDITOR
string FUID = FirebaseManager.ins.FireAuth.FUID;
#else
string FUID = "Test";
#endif
await FirebaseManager.ins.Firestore.UpdateData<UserData>(FirestoreCollections.UserData, FUID,
DataManager.Instance.userData);
OnDownloadCompleted?.Invoke();
}
else
{
OnDownloadFailed?.Invoke(new Exception("Topic ID를 서버에서 찾지 못 했습니다."));
}
}
catch (Exception e)
{
OnDownloadFailed?.Invoke(e);
}
}
| UI 구성 및 추가
업데이트 팝업 UI의 경우 타이틀 - 본문 (토픽 데이터, 스크롤뷰) - 하단 버튼의 형식으로 구성하였습니다.
아직은 기능 구현의 단계이기 때문에 UI가 단순합니다.
로그인이 진행된 후, 메인 씬에 진입 시 업데이트를 체크하여 아래와 같이 팝업이 뜨게 해 두었습니다.
추가로 첫 접속 시에는 가지고 있는 데이터가 없기 때문에 최소 1개 데이터를 다운로드하도록 강제하였습니다.
이때 경고, 다운로드 완료, 다운로드 실패에 대한 결과를 유저에게 보여주기 위해 추가 Popup, PopupManager를 구현해 두었습니다.
private async void OnUpdateButtonClicked()
{
var selectedSlots = _topicSlots.Where(slot => slot.IsSelected).ToList();
if (DataManager.Instance.userData.LocalTopicDataIDs.Count == 0 && selectedSlots.Count == 0)
{
PopupManager.Instance.ShowPopup("경고",$"최소 1개 이상 슬롯을 선택 해야 합니다.");
return;
}
foreach (var slot in selectedSlots)
{
await updateManager.DownloadTopicData(slot.GetTopicData().ID);
}
}
| 기존 더미 데이터 플레이 로직 수정
이전에는 로컬에 저장된 더미 데이터를 기반으로 플레이하도록 로직이 구성되어 있습니다.
이 로직을 Firestore의 데이터를 로컬의 저장 후 해당 데이터로 플레이할 수 있도록 씬 분리와 로직 수정을 하였습니다.
| 작업 결과 ✅
| 다음에 작업할 내용 🕟︎
이제 완성된 픽셀 아트들을 컬렉션에 기록하는 기능을 구현할 예정입니다.