Unity | 파이어베이스 데이터베이스 읽기 쓰기

Clean·2025년 7월 18일

Unity

목록 보기
23/24
post-thumbnail

오늘 배운 것

  • 데이터베이스 쓰기

  • 데이터베이스 읽기


파이어베이스 데이터베이스 추가

유니티패키지를 추가하고 SDK도 새로 받아서 기존의 google-services.json와 교체해야한다.

그리고 유니티에서 데이터베이스를 사용하기 전

CheckAndFixDependenciesAsync() 에서 파이어베이스를 사용가능 체크를 한 후

static 변수에 DB = FirebaseDatabase.DefaultInstance; 로 데이터베이스의 인스턴스를 할당했다.


데이터베이스 쓰기

데이터베이스에 데이터를 저장하는 함수는 총 5가지이며, 매개변수로는 주로 Object 타입을 받는다.

저장할 수 있는 자료형은 아래와 같다.

  • string
  • long
  • double
  • bool
  • Dictionary< string, object >
  • List< object >

SetValueAsync(object)

매개변수로 object 타입을 받으며, 이 데이터를 해당 경로에 덮어쓴다.

// RootReference = 최상위 부모
DatabaseReference reference = FirebaseManager.DB.RootReference;
reference.SetValueAsync(new List<string>() { "Test1", "Test2", "Test3" });
reference.SetValueAsync(new List<string>() { "Test4", "Test5" });

reference 경로에 리스트를 두 번 저장하면 어떻게 될까?

Test1, Test2, Test3 이 먼저 저장되고, 그 위에 Test4, Test5 가 저장돼서
Test4, Test5, Test3 이 된다고 생각할 수 있지만,

결과는 Test4, Test5 만 저장된다.

그 이유는 SetValueAsync() 는 기존 데이터를 삭제하고 새 값으로 덮어쓰기 때문이다.

즉, Test1, Test2, Test3 는 삭제되고 Test4, Test5 가 새로 저장된다.


SetRawJsonValueAsync(string)

매개변수로 string(JSON) 타입을 받으며, 해당 경로에 JSON 데이터를 덮어쓴다.

// 테스트 클래스들
[Serializable]
public class TestClass
{
	public string UserName;
	public int Level;
	public string Class;
	public int Hp;
	public List<Inventory> Inventory;
}

[Serializable]
public class Inventory
{
	public string ItemName;
	public int ItemCount;
}

_testClass = new()
{
	UserName = "Clean",
	Level = 99,
	Class = "전사",
	Hp = 104,
	Inventory = new()
	{
		new () { ItemName = "사과", ItemCount = 5, },
		new () { ItemName = "레몬", ItemCount = 10, },
	}
};

DatabaseReference reference = FirebaseManager.DB.RootReference;
reference.SetRawJsonValueAsync(JsonUtility.ToJson(_testClass)); // JSON 으로 변환

클래스나 구조체도 JSON 구조로 바꾸기 때문에 저장할 수 있고,

List<Dictionary<string, object>> 같은 구조는 사용할 수 없기 때문에

클래스나 구조체로 중간 단계를 만들어서 사용하면 된다.

또한, DatabaseReference userInfo = reference.Child("UserData").Child(user.UserId) 와 같이

root/UserData/UID 주소로 저장하면 UserData 폴더에 각 유저들의 ID로 저장할 수 있다.


UpdateChildrenAsync(IDictionary<string, object>)

딕셔너리의 Key(string)는 경로, Value(object)는 저장할 값이며,
해당 경로에 있는 데이터만 부분적으로 수정한다.

DatabaseReference reference = FirebaseManager.DB.RootReference;
Dictionary<string, object> data = new();
data["UserName"] = "클린";
data["/Class"] = "도적";
data["/Inventory/0/ItemCount"] = 20;
reference.UpdateChildrenAsync(data);

덮어쓰는 SetValueAsync()SetRawJsonValueAsync() 와 다르게

데이터베이스에 있는 Key에 해당하는 경로의 값만 수정할 수 있다.

Key에 경로인 '/' 를 넣든 안넣든 경로는 reference/UserName, reference/Class 가 된다.

그리고 Key는 결국 경로라 .Child() 를 사용해도 되지만, '/' 로 접근할 수 있다.


RunTransaction()

DatabaseReference reference = FirebaseManager.DB.RootReference;
reference.RunTransaction(task =>
{
	var test = task.Value;

	Debug.Log(test);

	return TransactionResult.Success(task);
});

이런식으로 디버그 찍으면서 보고있는데.... 값이 하나도 안온다 왜이러지?


데이터베이스 읽기

GetValueAsync()

해당 경로의 데이터를 비동기로 읽어온다.
결과는 task.IsFaulted, task.IsCompleted, task.Result 등을 통해 알 수 있고,
DataSnapshot 타입에 할당하여 사용한다.

DatabaseReference reference = FirebaseManager.DB.RootReference;
reference.GetValueAsync()
	.ContinueWithOnMainThread(task =>
	{
		if (task.IsFaulted)
		{
			Debug.LogError("읽기 실패");
			return;
		}

		DataSnapshot snapshot = task.Result;
	});

읽어온 데이터를 DataSnapshot 타입 변수에 할당하고, snapshot.Value 로 읽어온 데이터를 알 수 있다.


Dictionary<string, object> 로 파싱

DataSnapshot snapshot = task.Result;

if (snapshot.Exists)
{
	Dictionary<string, object> data = snapshot.Value as Dictionary<string, object>;

	if (data != null)
	{
		foreach (var kvp in data)
		{
			Debug.Log($"{kvp.Key} : {kvp.Value}");
		}
	}
}

JSON to 클래스

DataSnapshot snapshot = task.Result;
string json = snapshot.GetRawJsonValue();
TestClass data = JsonUtility.FromJson<TestClass>(json);

Debug.Log($"이름: {data.UserName}, 레벨: {data.Level}");

snapshot.GetRawJsonValue(); 을 통해 데이터를 JSON 구조로 받아올 수 있으며,

JsonUtility.FromJson<T>() 로 다시 클래스로 변환할 수 있다.


0개의 댓글