BlazorクライアントアプリケーションをFirebase Hostingにデプロイし、Firebase Databaseと連携したいと思います。
開発環境
Windows10
Visual Studio 2019 Preview
.Net Core 3.0 Preview 9
Firebase CLI for Windows(beta)
Firebaseの準備
Firebase-CLIを使えるようにする
VisualStudioのプロジェクトをFirebaseにデプロイするために、Firebase-Cliを準備します。Firebase CLI for Windows(beta)は、Node.jsなどのインストールが不要なので便利です。
Firebaseにログインし、新しいプロジェクトを作成
Firebaseアカウントを作成し、ログインして、新しいプロジェクトを作成します。
左側の開発メニューから「Authentication」を選択し、認証方法を設定します。今回は匿名(anonymous)を有効にします。
Firebase Databaseの作成
左側の開発メニューから「Database」を選択し、データベースの作成を行います。
保護ルールは、「テストモードで開始」を選択し、ロケーションはデフォルトのままにします。
Database (Realtime Database)の「ルール」で、.read:true , .write:true になっていることを確認します。
なっていない場合、画面上で書き換えます。
Firebase Databaseの設定はこれで終わりです。Firebase Databaseは「Realtime Database」を使います。
マイアプリの追加
Firebaseの左側の歯車メニューから「プロジェクトの設定」を選びます。
「全般」の「マイアプリ」のウェブアプリ「>」を選択します。
アプリの登録で「アプリのニックネーム」を付け、「アプリを登録」します。「□このアプリのFirebase Hostingも設定します」はチェックを外した状態で登録します。
次画面で出てくる Firebase SDKの追加画面では、apikey情報が表示されるので控えておきます。
今回必要になるのはapikeyとdatabaseURLです。
ベースのプロジェクトをデプロイ
VisualStudio2019 でBlazorクライアントアプリケーションを作成
新しいプロジェクトから、Blazorアプリを選択し、「Blazor WebAssembly App」を選択します。Server-Sideはホスティングしませんので、「ASP.NET Core hosted」はチェックしないで作成します。
何もしない状態で、デプロイしてみる
こちら様のサイトを参考に、Firebase Hostingにデプロイしてみます。
(参考)Qiita Blazorで作成したウェブサイトをFirebaseで公開する
firebase deploy
コマンドの途中でHTTP Error: 503エラーが発生する場合は、何度か試すと成功します。
以上でFirebaseの設定は完了です。
BlazorアプリのFetchDataのページをFirebase Databaseと連携させる
デフォルトのFetchDataページは、静的ファイルの中身を表示しているだけのものです。Firebase Databaseと連携させます。
Firebase Nugetパッケージの追加
FirebaseAuthentication.net と FirebaseDatabase.netを「Nugetパッケージの管理」から追加します。
(参考)FirebaseAuthentication.net
(参考)FirebaseDatabase.net
Pages/FetchData.razorのWeatherForecastをModel.csに移動
Model.csを新規作成し、モデルクラスとなるPages/FetchData.razorのWeatherForecast定義を移動します。
namespace BlazorApp
{
public class Model
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public string Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}
}
Firebaseアクセス用のAPIクラスを追加
Firebase Databaseとやりとりを行うAPI.csを新規に追加します。
実装するのは、認証とデータの取得、追加を行う関数です。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
// 参照の追加
using Firebase.Database;
using Firebase.Database.Query;
using Firebase.Auth;
namespace BlazorApp
{
public class API
{
private FirebaseAuth _auth = null;
public async Task Auth()
{
try
{
if (_auth == null)
{
// Firebase Database apiKey
var auth = new FirebaseAuthProvider(new FirebaseConfig("Firebase Database apikey"));
_auth = await auth.SignInAnonymouslyAsync();
Console.WriteLine("Auth OK");
}
}
catch
{
Console.WriteLine("Auth NG");
}
}
private ChildQuery GetDatabaseQuery(string path = null)
{
Console.WriteLine("GetDatabaseQuery Start");
if (_auth == null)
{
throw new NullReferenceException();
}
Console.WriteLine("GetDatabaseQuery End");
return new FirebaseClient(
// Firebase Database databaseURL
"https://Firebase Database databaseURL.firebaseio.com",
new FirebaseOptions
{
AuthTokenAsyncFactory = () => Task.FromResult(_auth.FirebaseToken),
})
.Child(path);
}
/// <summary>
/// Firebase Databaseからデータ取得
/// </summary>
/// <returns></returns>
public async Task<Model.WeatherForecast[]> GetData()
{
Console.WriteLine("GetData Start");
try
{
var query = GetDatabaseQuery("/WeatherForecast");
var result = await query.OnceAsync<Model.WeatherForecast>();
var resultobject = result.Select(o => o.Object);
Console.WriteLine("Object count:" + resultobject.Count().ToString());
Console.WriteLine("GetData End");
return resultobject.ToArray();
}
catch
{
Console.WriteLine("GetData NG");
return null;
}
}
/// <summary>
/// Firebase Databaseへデータ追加
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public async Task SetData(Model.WeatherForecast value)
{
Console.WriteLine("SetData Start");
try
{
var query = GetDatabaseQuery("/WeatherForecast");
await query.PostAsync(value);
Console.WriteLine("SetData End");
}
catch
{
Console.WriteLine("SetData NG");
}
}
}
}
Pages/FetchData.razorからAPI.csを呼び出す
最後に FetchData.razor内で、API.csの処理を呼び出します。
@page "/fetchdata"
@inject HttpClient Http
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
<div style="display:inline-flex">
<p>Date</p>
<input type="date" @bind-value="addItem.Date" />
<p>Temp. (C)</p>
<input type="text" @bind-value="addItem.TemperatureC"/>
<p>Temp. (F)</p>
<input type="text" value="@addItem.TemperatureF"/>
<p>Summary</p>
<input type="text" @bind-value="addItem.Summary"/>
<button class="btn btn-primary" @onclick="SetWeatherForecast">Add</button>
</div>
<br />
<br />
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
//WeatherForecast[] forecasts;
// 表示用データ
Model.WeatherForecast[] forecasts;
// 追加用データ
Model.WeatherForecast addItem;
// Firebase APIクラスのインスタンス
API firebaseAPI = null;
protected override async Task OnInitializedAsync()
{
//forecasts = await Http.GetJsonAsync<WeatherForecast[]>("sample-data/weather.json");
addItem = new Model.WeatherForecast();
addItem.Date = DateTime.Now;
// データ取得
await GetWeatherForecast();
}
//public class WeatherForecast
//{
// public DateTime Date { get; set; }
// public int TemperatureC { get; set; }
// public string Summary { get; set; }
// public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
//}
// データ取得
async Task GetWeatherForecast()
{
if(firebaseAPI == null)
{
firebaseAPI = new API();
}
// 認証後、Firebase Databaseから取得
await firebaseAPI.Auth().ContinueWith(async task =>
{
forecasts = await firebaseAPI.GetData();
this.StateHasChanged();
});
}
// データ設定
async void SetWeatherForecast()
{
if (firebaseAPI == null)
{
firebaseAPI = new API();
}
// 認証後、Firebase Databaseへ追加、その後、データ再取得
await firebaseAPI.Auth()
.ContinueWith(async task1 =>
{
await firebaseAPI.SetData(addItem).ContinueWith(async task2 =>
{
await GetWeatherForecast();
});
}
);
}
}
プロジェクトを発行して、Firebase Hostingへデプロイする
プロジェクトを発行後、Firebase CLIから firebase deploy
コマンドでデプロイします。
デプロイ後、アプリケーションのURLを開き動作を確認します。
Firebase Databaseの状態
データが追加されたFirebase Databaseには、ツリー上にデータが出来上がっているのが確認できます。
うまく動作しない時は
Blazorで作成したクライアントアプリケーションのデバッグは容易ではありません。そこで、ソースではConsole.WriteLine()
を使いログを吐き出し、Chromeなどのデバッグ画面を使って、コンソールログを確認します。
関連記事
Blazorで作成したウェブサイトをFirebaseで公開する
C#でFirebaseを使ってみよう!(1) FirebaseとEmail-Password認証
C#でFirebaseを使ってみよう!(3) Databaseを使ってみる