消防設備計算アシスタントアプリを開発
はじめに
以前、電気設備の設計や検討を簡単に計算をできるアプリを開発しました。
今回は、消防設備の確認に役立つアプリを開発しようと思い、消防設備計算アシスタントというアプリをFlutterで開発し、Google PlayとApp Storeでリリースしました。
apps.apple.com目次
開発背景とターゲット
電気設備計算アシスタントと同様に、自分の業務で使用できないかなと思い立ったのがきっかけです。
消防設備専門で働かれている方々は、ほとんどの法令や規格が頭の中に入っていると思うのですが、私のような普段は消防設備業務を行っていないが、時々確認する必要がある人は、法令や参考書を見て判断する必要があります。
また、消防設備士試験の試験勉強では能力単位の計算や設置義務判断が必要となります。
そこで、上記のユーザを本アプリのターゲットとし、簡単に結果が確認できるように設計しました。
なお、消防設備の工事や点検には各類別の「消防設備士」資格や着工届等が必要なので、アプリだけでは業務を遂行できず、あくまで「アシスタント」という位置づけです。
今回の開発でチャレンジしたこと
今回のアプリ開発で新しく挑戦したことをまとめます。 (一部は直前のアプリ更新で挑戦したことも含まれます。)
- RiverpodのStateNotifierProviderとfreezedの導入
状態管理にRiverpodを使っていますが、よりMVVMを意識して、StateNotifierProviderとfreezedを採用しました。 慣れが必要ですが、複雑な状態の更新をより簡単にすることができました。
- スプラッシュ画面の導入
スプラッシュ画面があればかっこいいなくらいの気持ちで実装しました。
flutter_native_splash
を使うと、Flutterで簡単にスプラッシュ画面を実装できました。
- テストコードの実装
これまではRiverpodのテストがうまく動かなかったため、あまりテストコードを書いていませんでしたが、(正しいかわからないけど)動作するようになったので、unit testのコードを作成してテストを行いました。
以下は、Riverpodでのテストの例。
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { test('Riverpod test', () { /// ProviderContainerの定義 final container = ProviderContainer( overrides: [ aProvider.overrideWithValue(aNotifier()), ], ); /// 状態の確認 expect(container.read(aProvider).xxx, 0); /// 値を変更 container.read(aProvider.notifier).updateXxx(1); }); }
- リワード広告の実装
半分以上趣味で作っているのと、その他事情により、マネタイズは広告のみですが、バナー広告だけではなく、リワード広告も実装しました。 リワード広告といっても報酬が無いので、運用方法は今後も検討していきたいと思います。
今後の展開
消防設備計算アシスタントもスモールスタートで始めた(初期開発時間が数十時間)ので、アップデートで機能の追加を行っていきたいと考えています。
以下は今後実装したい機能の一例です。
- 避難器具の設置義務の計算
- 消火器の適応判断
- 自火報設置個数計算
- 市町村条例に応じた計算や判断
etc...
アプリのサポートページにも記載しています。
おわりに
アプリにミス等があればご報告いただけると嬉しいです。 また、アプリの評価もしていただけると嬉しいです。
なお、今回のアプリのコードは、Githubで公開しています。
Next.js + Cloudflare Pages でポートフォリオを作成
はじめに
これまで、アプリ情報サイトやポートフォリオをGithub pagesで公開していましたが、よりカスタマイズされたサイトを製作したいと思い、静的サイトジェネレータ(SSG)とホスティングサービスを使ってwebサイトを作りました。
まだ完成していませんが、デプロイまでできたので、一旦ブログでまとめます。
目次
技術選定
今回は静的なサイトを構築できるSSGを選択していますが、そもそも、CMSではなくSSGを選択した理由について、
- コスト削減
- 管理工数やセキュリティリスクの低減
- 高速な表示
これを踏まえて、SSGとホスティングサービスを選定しました。
SSGの選定
SSG自体は基本的な機能が揃っていて、無料(できればライセンスのゆるいOSS)であれば、特にこだわりがなかったので、Githubで人気だったNext.jsを選択しました。
ホスティングサービスの選定
前提として、信頼性が比較的高く、まずは無料で使えるサービスを検討しました。 最終的には、Netlify, Vercel, Cloudflare Pages, Firebase Hostingの中から選ぶことになりましたが、以下の理由からCloudflare Pagesを選定しました。
- Netlify : 通常プランは初回読み込みが遅い
- Firebase Hosting : 単にホスティングするには機能が多すぎる&無料枠の制限が厳しい
- Vercel : 無料プランはNon-commercial専用(今のところ、広告の貼付やオンラインビジネスを行う予定はありませんが、今後のことも考えて)
- Cloudflare Pages : 転送量が無制限で、初回読み込みも高速、商用利用可能
はじめはNetlifyを使用していましたが、テストで作った簡単なページの表示が数秒以上かかったので、やめました。 調べてみると、どうやら通常プランでは日本リージョンが無いため、遅くなっているようです。
開発環境
Node.js環境はすでに構築済として進めます。
Next.jsの導入とチュートリアル
導入は以下のコマンドを入力するだけです。
npx create-next-app@latest
まずは、Next.jsに慣れるため、公式チュートリアルをしました。
すべて一通り実施できたら、markdownでブログを作ることができるレベルまで上達します。 わからないことは公式ドキュメントで調べます。
vscodeの設定
vscodeで開発を進める場合、ESlintの設定を行います。
プロジェクトのルートで
./node_modules/.bin/eslint --init
.eslintrc.json
の中に"extends": "next/core-web-vitals"
を追記します。
以下は一例です。
{ "env": { "browser": true, "es2021": true }, "extends": ["eslint:recommended", "next/core-web-vitals"], "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, "rules": {} }
Next.jsでサイト構築
公式チュートリアルを実施していれば、ある程度できるようになっています。 作成する上で悩んだ点をまとめます。
Vercelを使わない場合、画像の最適化は別のloaderを使うかimgタグを使う
デフォルトのloaderではVercel以外では使えないみたいなので、imgix等のloaderを使用しなければいけません。
もしくは、最適化はできないけど、img
タグを使って画像を表示することもできます。
<img src="/images/profile.jpg" height={108} />
markdownのパース
markdownのパースにはremark
を採用し、プラグインとしてremark-html
, remark-image
, remark-gfm
を使いました。
以下は使用例。
import { remark } from "remark"; import html from "remark-html"; import remarkImages from "remark-images"; import remarkGfm from "remark-gfm"; const processedContent = await remark() .use(html, { sanitize: false }) .use(remarkGfm) .use(remarkImages) .process(data); const contentHtml = processedContent.toString();
デプロイ準備
npx next build
とnpx next export
を実施し、問題が発生しないか確認します。
静的HTMLのexportは画像最適化等がexportに対応していないので、注意が必要です。
Cloudflare Pagesの始め方
サインアップ
公式サイトからサインアップします。
Githubアカウントと連携しデプロイ
ダッシュボードからPagesへ飛び、プロジェクトを作成します。
ビルドの設定ではフレームワークにNext.jsを選択します。 必要に応じて、環境変数を設定できます。
保存するとデプロイが開始され、完了したら、公開アドレスが表示されます。
また、以後はリポジトリに変更がpublishされる度に、ビルドを行います。
カスタムドメイン
Google Domainsを使ったカスタムドメインの設定です。
Cloudflare Pagesのプロジェクトの中からカスタムドメインを設定します。
Cloudflare Pagesに記載された名前とターゲットをGoogle DomainsのDNS > カスタムレコード(CNAME)のホスト名とデータに書きます。
Google Domains側で保存できたら、Cloudflare Pages側からDNSレコードを確認します。 完了後、新しいサブドメインを使うことができます。
おわりに
普段、JavascriptやReactを使わないので、やや難しく感じる部分がありましたが、少ないコードで静的サイトを構築することができました。
まだまだ甘い部分もあるので、これからきれいにしていきたいと思います。
自分のドメインを取得した話
きっかけ
数年前に自分のドメインを取得していましたが、特に使うことがなかったので、やめてしまいました。
しかし、最近になって以下の問題からドメインを取得することになりました。
- アプリ用のサポートサイトをGithub Pages(
username.github.io
ドメイン)で公開していたが、他人のドメインなので信用がなく、決済プラットフォームの審査に落ちた - アプリ公開時のメールアドレスに自分のGmailが公開されるのは抵抗があった
- いろんな人の記事を見ていて、自分のドメインが欲しくなった
そこで、今回はドメインの取得についてのメモをまとめました。
目次
ドメインの取得
まずはドメインを検索します。 いろいろなサービスがありますが、私は以下の理由からGoogle Domainsを選択しました。
- オプションも含め更新時のトータル費用が安い(新規取得は他サービスのほうが安いが、長期的に使用することを考えたら...)
- Google Cloud系のサービスを使っている
- Googleなのでセキュリティ面は比較的信頼できる
- 管理画面がシンプルで見やすい
- 以前、とあるドメインサービスを使っていたが、スパム並みにメールが来ていたのが嫌だった
お気に入りのドメインを検索して購入。 年間1400円なので、あまり気にしなくていい金額です。
必要項目を入力し問題なければ、登録完了メールが届きます。
メールの転送設定
カスタムドメインのメールを自分のGmailで受信
カスタムドメインのメールを自分のGmailで受信する場合の設定方法について。 Google Domains > メールアドレス > メール転送 > メールエイリアスの追加 で新しいカスタムドメインのメールアドレスと転送先のGmailアドレスを設定すれば完了。
カスタムドメインのメールを自分のGmailから送信
Gmailのエイリアスを使ってカスタムドメインからメールを送信する場合の設定方法は公式サイトの通りに進めるとできます。
Googleアカウントの2段階設定を行い、アカウント > セキュリティからアプリパスワードの設定を開始します。
「アプリを選択」の項目はメール、「デバイスを選択」の項目はその他にして、「名前」はわかりやすい名前にします。
生成したら、パスワードを暗記します。
ここから、Gmailの設定。 設定 > アカウントとインポート > 名前にある他のメールアドレスを追加をクリックします。
カスタムドメインのメールアドレスと表示名を入力します。
「SMTPサーバー」はsmtp.gmail.com
、「ポート」は587
、「ユーザー名」はGoogleアカウントのログインユーザー名、「パスワード」はGoogleアカウントのアプリのパスワードで設定した16文字のパスワードを入力し、アカウントを追加します。
メールがカスタムドメインのアドレスに送られるので、リンクをクリックします。 テストのため、適当なメールを自分のGmail宛てに送信して、問題なければ完了です。
Firebase hostingのカスタムドメイン設定
実験としてFirebase hostingのカスタムドメイン設定をします。
Google Domainsからカスタムレコードへ移動し、「タイプ」にCNAME、「TTL」に3600、「データ」に現在のURLを入力します。
保存したら、Firebase hostingに移動し、カスタムドメインを追加します。
最大24時間待って、アクセスできたら完了です。
今後について
自分のドメインが獲得できたので、ホスティングサイトでカスタムドメインを設定しようと思います。 webアプリや新しくブログを公開するのもいいですね。