この記事はNAIST Advent Calendar 2022 24日目の記事です。
前書き
僕はこのエスプレッソマシンとその他のコーヒー関係の会計を担当しています。もちろん残高のチャージとかも僕が担当しています。
この支払いシステムはQRコードの認識だけでは成り立ちません。認証と残高の調整等を行うサーバ、またQRコードを表示するなどのインターフェースも必要となります。
もちろん前の記事で実装したものよりは実装が簡単であり、技術的にすごいとは言えないですが、書いていこうかなと思っています。また、自分はFirebaseをプロダクトで使用するのは初めてだったので、結構めちゃくちゃな設計をしていたりしますが、大目に見てください....
何で実装するか
サーバ
NAISTの中の適当なサーバにバックエンドを置いて運用するのも検討しましたが、手続き的に面倒なので外部にサーバを置くことにしました。しかし、VPSなどは月額料金が高く、マシンで取れる利益よりサーバ代が高いかもしれない問題と維持保守が難しい問題がありました。そこで導入すると決めたのがFirebaseです。
Firebaseはサーバを自前で構築する必要がなく、APIを通してデータベースの操作、認証そしてホスティングなど、ウェブサービス運用に必要な様々なものを提供してくれるサービスです。無料枠もかなり大きく、身内+α程度しか使わないシステムはこれで十分かと思いました。
フロントエンド
最初はiOSとAndroidの専用アプリを製作するのも考えていましたが、App Store(iOS)にアプリを出すだけで年間99ドルが必要なことがわかりました。Androidのデベロッパーアカウントは持っているので追加的な支払いなしに公開はできたのですが、自分含めiOS機種をメインで使っている人が何人かいたのでAndroidのみにするのもできませんでした。
そこで選んだのがWebフロントエンドです。フレームワークとして選んだのは学部時代から使ってきてある程度慣れているNuxt.jsを使用することにしました。また、Vuetifyを使ってUIをそれっぽくしています。Firebase Hostingでホスティングしています。
実装方法
サーバ
利用サービス
データベースはRealtime Databaseを使用しています。Firestoreのほうが高機能なのはわかっていますが、実装がしやすいとの理由で自分がWebクライアントに取り掛かる前からshirunariさんが先にRealtime Databaseを使うのを前提としてハード側の実装を進めてきました。自分もそれに合わせてRealtime Databseを使ってシステムに必要な他のデータを保持する実装を進めてきました。
また、認証はFirebase Authenticationを使用しています。Firebase Authenticationを利用することにより、Realtime Databaseのアクセス制限をAuthentication情報で行うことが可能となり、セキュリティ設定を簡単に行うことができました。ただ、UIDが長かったのでどうしても認証情報が長くなり、QRコードが大きくなったことからpuiさんが実装で結構苦労してました...
支払いの処理や会員登録などの処理はFirebase Functionsで行っています。これらの操作は、Realtime Databseのルール設定だけでは望むようなセキュリティが確保できず、Functionsで行うことにしました。
使用したFirebaseのサービスは以上です。
Functionsで実装した機能
Functionsでは、認証プロセス等を行っています。すべての事項について述べることはできませんが、認証プロセスについて簡単な説明を行いたいと思います。
認証は、UID、認証コード、支払額の情報をHTTPS経由で受け取り、UIDの会員情報の認証コードと一致するかを確かめます。その後、残高を減らし、ボタンを押す許可を出す仕組みです。認証コードは認証に成功するとFunctionsで更新し、同じQRコードを支払にに使うことはできません。
フロントエンド
FirebaseのクライアントAPIを用い、JavaScriptでデータベースからの読み込み、書き込みを行っています。使い方は非常に簡単で、データベースとのデータのやり取りに関してはあまり悩んでいませんでした。
ウェブページはメインページ、QRコードページ、アカウント情報、お問い合わせなどで構成されています。それぞれは複数のhtmlファイルで分けず、SPA(Single Page Application)で書き出し、Firebase APIを用いたやり取りによりJavascriptで表示を変更しています。
表示されるQRコードはUID,認証コード,支払い額
のテキスト情報を持っています。上述の通り、認証コードは支払いが行われるたびに変更され、ユーザが直接更新することも可能です。そのため、QRコードだけを保持して他人が使おうとしても認証エラーが発生する仕組みになっており、ある程度セキュリティを確保しています。
実際のQRコード画面です。1カップ、2カップのボタンを押すと後ろの支払額が変更されます。Refreshを押すと認証コードが更新されます。
改善したいところ
管理者ページ
まだ管理者ページを作成していません。今はFirebase RealtimeDatabaseのページで直接値をいじっています。改善したいところですがなくても困らないから正直やる気が出ません...
支払い履歴の記録
今の実装だと支払額をUIDのユーザから減らすだけなので、支払履歴が残りません。そのため、支払の取り消しをするためには直接値をいじる必要があります。後に追加していきたいと思います。
終わりに
残念ながら、セキュリティ上の都合で公開できるところは非常に限られ、FirebaseとNuxt.jsでサーバとウェブフロントエンドを実装したとしか公開できません。しかし、NAISTのみなさんなら、体験することは可能です。体験の申請などは随時受け付けています。使ってみたい方はご連絡ください。