C#/ASP.NET Core

[Asp.net core] Firestore 저장할 때 자료형 주의할 거

말하는 닭 2023. 5. 7. 17:26

 

Firestore에 자료를 저장하려면

FirestoreDb db = FirestoreDb.Create(Project_Id);
DocumentReference docRef = db.Collection(Collection_Name).Document(Document_Name);

//저장할 때
await docRef.SetAsync(data);

//가져올 때
DocumentSnapshot snapshot = await docRef.GetSnapshotAsync();
Dictionary<string, object> data = snapshot.ToDictionary();

위와 같이 간단하다. 

 

 

그런데, 파이어스토어는 number, boolean, string, map, array... 이런 거 밖에 저장할 수 없다. List형은 array로 바뀌어 저장이 되지만, List<CustomClass>같은 경우는 저장이 안 된다.

 

그래서 이 경우는 Json형태로 직렬화하여 문자열 형태로 저장해야 한다.

값을 가져올 때는 Json형태로 받아지므로 역직렬화하면 된다.

 

아래는 예시

 

Set

Dictionary<string, object> setData = new Dictionary<string, object>() {
    { "Name", name },                                    //string
    { "Description", description },                      //string
    { "GeoPoint", new GeoPoint(latitude, longitude) },   //GeoPoint
    { "Reviews", JsonConvert.SerializeObject(reviews) }, //List<Review>
    { "Menus", JsonConvert.SerializeObject(menus) },     //List<Menu>
    { "Tags", JsonConvert.SerializeObject(tags) },       //List<Enum>
    { "LikeCount", 0 },                                  //int
};
await docRef.SetAsync(setData);

 

Get

var data = document.ToDictionary();  //Firestore에서 받아온 자료

Restaurant restaurant = new Restaurant() {
    Name = data["Name"].ToString()!,
    Description = data["Description"].ToString() ?? string.Empty,
    GeoPoint = (GeoPoint)data["GeoPoint"],
    Menus = JsonConvert.DeserializeObject<List<Menu>>(data["Menus"].ToString()),
    Tags = JsonConvert.DeserializeObject<List<Tag>>(data["Tags"].ToString()),
    LikeCount = Convert.ToInt32(data["LikeCount"])
};
Menus = JsonConvert.DeserializeObject<List<Menu>>(data["Menus"].ToString()),

다음과 같이 가져와서 역직렬화 시켰다. 여기서 JsonConvert는 Newtonsoft.Json 을 가져와서 사용했다. (그냥 파이어스토어 패키지 설치하면 자동으로 같이 설치됨)

 

참고: int형은 Firestore에 int64로 저장이 된다. 그래서 가져와서 쓰려면 int32로 바꿔줘야 되는데, 그냥 (int)data 이런 식으로 바꾸면 에러난다. 못바꾼대요. >> Convert.ToInt32를 써서 바꿔줬다.

 

GeoPoint(Firestore에 저장할 수 있는 형태 중 하나)의 경우는 그냥 (GeoPoint)로 바꿔줄 수 있나보다. 딱히 에러는 안 나는 것 같다.

 

 

그리고, class를 직렬화할 때에는 반드시 아래와 같이 [Serializable] 을 붙여줘야 한다. 아니면 직렬화를 할 수 없는 듯하다. 만일 class안에 또 class가 있다면 그 아이도 [Seializable]을 붙여줘야 한다.

[Serializable]
public class Menu {
    ...
}