Unityでデータベースを利用したい人に向けたFirestore入門

## はじめに

Unityを利用したときにデータベースサーバーまで自分で構築するのは面倒ですよね。そんな時に便利なのが**クラウド・データベース**です。

クラウド・データベースにはいくつか種類がありますが、今回は**Firestore**について紹介しようと思います。

:::note info
Firestoreについてはすでに数多く存在しているので、それらの記事を紹介しつつ自分なりにまとめるという形にしています。
:::
## Firestoreとは

Google社が提供する**NoSQL型**のデータベース

## NoSQLとは

NoSQLとは**Not only SQL**の略で関係データベース以外のデータベースを指します。名前からしてNotSQL(SQLでない)に勘違いされることがありますが、れっきとしたSQLの一種です。

## Firestoreの構造

- リレーショナルデータベースでいうところのテーブルをコレクション、カラムをドキュメントIDという。
- jsonのような構造になっておりコレクションの中にドキュメントIDがある、ドキュメントIDの中にコレクションがある場合もある
- 最上位以外のコレクションはサブコレクションと呼ばれる

概要の把握についてはこちらの記事がわかりやすかったです

https://zenn.dev/yucatio/articles/173f386c471398

また、公式ドキュメントが日本語かつ量もそこまで多くないので読んでおくといいと思います。

https://firebase.google.com/docs/firestore/quickstart?hl=ja

## データの操作

以下のコードはC#によるものなので、他の言語の方は公式ドキュメントをご覧ください。

基本的にCollectionとidを指定してデータの操作をするイメージです

https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja

### INSERT

```csharp
dataBase = FirebaseFirestore.DefaultInstance;

// 追加データの用意
Dictionary<string, object> data = new Dictionary<string, object>()
{
   {"Name", "Hoge"},
};

// id未指定(自動で生成されます)
Task writeTask = dataBase.Collection(Collection).Document().SetAsync(data);

// id指定
Task writeTask = dataBase.Collection(Collection).Document(id).SetAsync(data);
```

### SELECT

```csharp
var db = FirebaseFirestore.DefaultInstance;
QuerySnapshot getData = await db.Collection(Collection).GetSnapshotAsync();
foreach (var document in getData.Documents)
{
    Dictionary<string, object> DictionaryData = document.ToDictionary();
    // idが一致するものを検索
		if (document.Id.Equals(id))
    {
				Debug.log(DictionalyData["Name"].ToString())
    }

}
```

### UPDATE

```csharp
var db = FirebaseFirestore.DefaultInstance;
Dictionary<string, object> data = new Dictionary<string, object>()
{
   {"Name", "sayyyyy"},
};

DocumentReference OriginData = db.Collectn(Collection).Document(id);

OriginData.UpdateAsync(data);
```

### DELETE

```csharp
var db = FirebaseFirestore.DefaultInstance;
DocumentReference DeleteData = db.Collection(Collection).Document(id);
DeleteData.DeleteAsync();
```

## 取得した情報の変換

取得してきたデータはそのままでは型が違うので利用できません。そのため取得してきたデータに対して**キャスト**する処理を記述してあげる必要があります。

```csharp
// String
docDictionary["path"].ToString();

// int
(int) Convert.ChangeType(docDictionary["path"], typeof(int));

// bool
(bool) Convert.ChangeType(docDictionary["path"], typeof(bool));

// array
(List<object>) Convert.ChangeType(docDictionary["path"], typeof(List<object>));

// timestamp
(Timestamp) Convert.ChangeType(docDictionary["path"], typeof(Timestamp));
```

## 詰まったところ

Firestore側で権限を変更するのを忘れていて、データベースにアクセスできませんでした。かなり時間を費やしました…

https://stackoverflow.com/questions/46590155/firestore-permission-denied-missing-or-insufficient-permissions

## auto incrementの実装

FirestoreはRDBMSと異なり、標準ではAuto Incrementをサポートしていないらしい。まあそりゃそうなんだけど…

実装する方法は下記記事で解説してくれていました。

https://dukesoftware00.blogspot.com/2021/09/firestoreauto-increment.html

## 参考資料

https://www.oracle.com/jp/database/what-is-a-cloud-database/

https://zenn.dev/yucatio/articles/173f386c471398

https://taidanahibi.com/unity/unity-firestore/

https://stackoverflow.com/questions/46590155/firestore-permission-denied-missing-or-insufficient-permissions

https://dukesoftware00.blogspot.com/2021/09/firestoreauto-increment.html

https://www.mongodb.com/ja-jp/nosql-explained

https://qiita.com/NWaka_1415/items/ac3d06ef8c350ba53160