Firebase Realtime Database を C# から利用する

# はじめに

Firebase Realtime Database を C# で利用する方法の紹介です。
今回は、FirebaseDatabase.net というライブラリを利用しました。

# Firebase Realtime Database とは

NoSQL クラウド データベースでデータの保管と同期を行うことができます。
データはすべてのクライアントにわたってリアルタイムで同期され、アプリがオフラインになっても引き続き使用できます。
公式ページは以下参照。
https://firebase.google.com/docs/database?hl=ja

Firebaseにはもう1つ Cloud Firestore というデータベースがあり、それとの違いは、インポート・エクスポート・一括更新に強く、書き込み・読み込みの頻度が高い場合にリーズナブルな所であり、容量1GBまでは無料利用可能です。
(Cloud Firestore の方が新しく、最近はそちらを使う人の方が多い気がします)
2つのデータベースの比較は、以下の記事を参照ください。
[Firebase Realtime DatabaseとFirestoreを使い分けていこうなという話](https://techblog.kayac.com/rtdb-vs-firestore)

# C#での使い方

FirebaseDatabase.net というライブラリを使えば、簡単に Firebase Realtime Database を利用できます。
公式サイトは以下を参照ください。
https://github.com/step-up-labs/firebase-database-dotnet

Nuget という C#でのパッケージマネージャからダウンロードしてインストール可能です。
以降で、このライブラリの利用方法を紹介します。

## 認証方法(サーバー側で secret を利用)

最もシンプルな認証方法は、サーバー側での利用の際に Firebase Realtime Database の secret と URL の2つを設定することです。
下図の赤枠部分を書き換えるのみです。
詳しくは、公式サイトの以下を参照ください。
[公式サイトの認証の説明はこちら](https://github.com/step-up-labs/firebase-database-dotnet#authentication)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/4932e371-f7be-f65f-d28c-3adde72f977f.png)

ただし、secret を用いた認証は Googleでは非推奨で、推奨する方法は以下に記載されています。
https://firebase.google.com/docs/admin/setup?hl=ja#c_1

## データの取得方法

認証用にFirebaseClientクラスのインスタンスを作ったあと、赤枠のような感じで取得できます。
Childメソッドでパスを指定して、OrderByXXXメソッドで取得する順序を指定して、StartAtでフィルタして、LimitToFirstで取得件数を制限しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/afdb12c4-d0f3-b428-018a-e25c516821f0.png)

以下に、実際に Firebase にあるデータを取得する例を記します。

まず、データを取得・更新するためのサンプルクラスを以下のように定義します。

```cs
public class TestRecord
{
	public string Id { get; set; }
	public int IntValue { get; set; }
	public string StringValue { get; set; }
}
```

そのクラスを用いて、下図のように Firebase にデータが格納されていると仮定します。
items以下の2つのデータが、上記クラスに相当するデータです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/f9857be2-c2e4-fe31-fb5d-5e350db8cc28.png)

上図のデータの items 以下の要素一覧を取得する場合は、以下のように実装します。
OrderByメソッドを用いて IntValue の昇順で取得しています。

```cs
var firebase = new FirebaseClient("https://xxx.firebaseio.com/");
var items = await firebase
	.Child("items")
	.OrderBy("IntValue")
	.OnceAsync<TestRecord>();
```

# データの編集方法

FirebaseClientクラスのインスタンスを作って、Childメソッドでパスを指定して、PutAsyncメソッドで登録および更新ができます。
同様に、DeleteAsyncメソッドで削除ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/d1423f37-e94a-dcaa-81fe-7c7a047136a0.png)

以下に、実際に Firebase にあるデータを更新する例を記します。

下図のデータに対して、Items以下に新しい要素を追加したい場合を考えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/f9857be2-c2e4-fe31-fb5d-5e350db8cc28.png)

 "items/XXX" というパスを指定して、新しく作成した TestRecord クラスのインスタンスを PutAsync メソッドで指定することで、 "items/XXX" というパスに新しいデータを追加できます。
なお、すでにそのパスが存在する場合は、上書き更新になります。

```cs
TestRecord testRecord = new TestRecord(){ IntValue = 20, StringValue = "hoge"};
var firebase = new FirebaseClient("https://xxx.firebaseio.com/");
await firebase.Child("items/XXX").PutAsync(testRecord);
```

# Azure Functions から利用する

よくあるユースケースとしては、Web APIを用いて、Firebase のデータを取得・更新することだと思います。
C# で Web API を作成する場合は、Azure Functions が便利です。

Azure には Azure Functions という Web API を公開できる機能があります。
Visual Sutudio を利用すれば、ポチポチボタンを押すだけで、簡単に Azure に Azure Functions を発行できます。
詳細な手順は以下を参照ください。
[クイック スタート: Visual Studio を使用して Azure で初めての C# 関数を作成する](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-create-your-first-function-visual-studio)

上記で Azure Functions のプロジェクトを Visual Studioで作成すると、メソッドのひな形まで作成されます。
あとは、そのメソッドの中身を書くだけで実現できます。

Firebase にアクセスするためのサービスを別途作ってあると仮定すると、実装イメージは以下のような感じになります。

```cs
[FunctionName("GetRecords")]
public static async Task<IActionResult> GetRecords(
    [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
    ILogger log)
{
    // Firebaseにアクセスするサービスを取得する
    var service = GetFirebaseService();
    // Firebaseからデータを取得する
    var records = await service.GetRecordsAsync<TestRecord>("items/");

    // 取得したデータを返す
    string responseMessage = string.Empty;
    foreach (var record in records)
    {
            responseMessage += record.ToString();
    }

    return new OkObjectResult(responseMessage);
}
```

Azure Functions から利用するサンプルプログラムについては、こちらに作成しましたので、よろしければ参照ください。
https://github.com/kojimadev/FirebaseRealtimeDatabaseService

# まとめ
Firebase Realtime Database を C# の Azure Functions から利用する方法を紹介しました。

ちなみに私は、普段はエンジニアリングマネージャーとして、チームの皆で楽しく開発する施策を色々実施しています。詳しくは以下を参照ください。
[1年以上かけて生産性倍増＋成長し続けるチームになった施策を全部公開](https://qiita.com/kojimadev/items/4b28f801863cf4e8f0da)

Twitterでも開発に役立つ情報を発信しています → [@kojimadev](https://twitter.com/kojimadev)