プログラミング学習日記

プログラミング学習時のメモ帳。

Unity firebase firestore 操作

間違っている場所あったら優しく教えてね

Unityでfirestureのデータベースを操作する.

初めにインスタンスを生成する.

// 使いまくる.
FirebaseFirestore db = FirebaseFirestore.DefaultInstance;

データを取得する.

このようなデータが格納されていたとしよう f:id:topazzz:20211005004337p:plain

// インスタンスに対してCollectionを指定してDocumentを指定する.ネスと構造でチェーンしていく
DocumentReference docRef = db.Collection("test").Document("test001");

// snapshotとして現在のデータベースの値を取ってくる.
docRef.GetSnapshotAsync().ContinueWithOnMainThread(task =>
            {
                DocumentSnapshot snapshot = task.Result;
                if (snapshot.Exists)
                {
                    Debug.Log(String.Format("Document data for {0} document:", snapshot.Id));

// snapshotの中身をDictionaryとして扱う.key,valueのpair
                    Dictionary<string, object> city = snapshot.ToDictionary();
                    foreach (KeyValuePair<string, object> pair in city)
                    {
                        Debug.Log(String.Format("{0}: {1}", pair.Key, pair.Value));
                    }
                }
                else
                {
                    Debug.Log(String.Format("Document {0} does not exist!", snapshot.Id));
                }
            });

データを登録する

データを登録する際にkeyとvalueのDictionaryを毎回作ってもいいがfirebaseには便利機能が付いている.FIrebaseDataFireBasePropertyアノテーションだ.
このようにアノテーションを追加したクラスを定義しておく.

[FirestoreData]
public class City
{
    [FirestoreProperty]
    public string Name { get; set; }

    [FirestoreProperty]
    public string State { get; set; }

    [FirestoreProperty]
    public string Country { get; set; }

    [FirestoreProperty]
    public bool Capital { get; set; }

    [FirestoreProperty]
    public long Population { get; set; }
}

この定義したクラス(Cityクラス)をそのままデータベースにいれることができる. ドキュメントが存在しない場合には新たに作成される,

// 初めにドキュメントへの参照を取得する.
DocumentReference docRef = db.Collection("test").Document("test001");
            City city = new City
            {
                Name = "Los Angeles",
                State = "CA",
                Country = "USA",
                Capital = false,
                Population = 3900000L
            };
// 参照に対してSetAsyncで登録する.
            docRef.SetAsync(city);

このdocReg.SetAsync(city)を使うとtest001のfieldが全てリセットされ新しく追加したcityのプロパティだけになる.SetOption.MergeAllをつけることで,新しく追加しないフィールドは放置しておき更新箇所だけをみることができる.

// 参照に対してSetAsyncで登録する.オプションをつける
            docRef.SetAsync(city, SetOptions.MergeAll);

データを取得する

基本的にはsnapshotを取ってきてから操作を行う

DocumentReference docRef = db.Collection("cities").Document("SF");
docRef.GetSnapshotAsync().ContinueWithOnMainThread(task =>
{
  DocumentSnapshot snapshot = task.Result;
  if (snapshot.Exists) {
    Debug.Log(String.Format("Document data for {0} document:", snapshot.Id));
// snapshotでfieldの値をDictionaryに置き換える.
    Dictionary<string, object> city = snapshot.ToDictionary();
    foreach (KeyValuePair<string, object> pair in city) {
      Debug.Log(String.Format("{0}: {1}", pair.Key, pair.Value));
    }
  } else {
    Debug.Log(String.Format("Document {0} does not exist!", snapshot.Id));
  }
});

これはこれで便利だが,Dictionary型はUnityとか言語で扱う際にとても面倒.先に定義したカスタムオブジェクトに変換することができる

DocumentReference docRef = db.Collection("cities").Document("BJ");

docRef.GetSnapshotAsync().ContinueWith((task) =>
{
  var snapshot = task.Result;
  if (snapshot.Exists)
  {
    Debug.Log(String.Format("Document data for {0} document:", snapshot.Id));
// Firebaseのアノテーションをつけておいたカスタムオブジェクトに変換する.
    City city = snapshot.ConvertTo<City>();
    Debug.Log(String.Format("Name: {0}", city.Name));
    Debug.Log(String.Format("State: {0}", city.State));
    Debug.Log(String.Format("Country: {0}", city.Country));
    Debug.Log(String.Format("Capital: {0}", city.Capital));
    Debug.Log(String.Format("Population: {0}", city.Population));
  }
  else
  {
    Debug.Log(String.Format("Document {0} does not exist!", snapshot.Id));
  }
});

Query について

ここに書かれてある通り Firebase.Firestore.Query Class Reference

ブログを見ていただきありがとうございました