- はじめに
- Firebaseが提供しているデータベースについて
- 環境
- 環境構築
- Realtime Databaseのデータ構造を構築する
- メンテナンスと強制バージョンアップのポップアップを表示する
- 参考サイト
はじめに
今回は、Angular(Ionic)で作ったアプリからFirebase Realtime Databaseを参照して、メンテナンスと強制バージョンアップを知らせるポップアップを表示する機能を作成します。
Firebaseが提供しているデータベースについて
まず、Firebaseが提供している二つのデータベースの違いについて説明します。
- Cloud Firestore
- データをドキュメントのコレクションとして扱う。多彩なクエリを使えるため検索に強く、Realtime Databaseよりも複雑で階層的なデータを扱いやすい
- Realtime Database
- データを単一のJSONツリーとして扱う。Cloud Firestoreよりもレイテンシーが低いため、データの同期が早い
Realtime Databaseではなく、基本的に後続サービスのCloud Firestoreを使ってください、と書かれている記事が多かったんですが、今回はデータのread/writeのスピードがより早いRealtime Databaseを採用します。
環境
TypeScriptベースのフレームワークであるAngularと、iOS/AndroidのハイブリッドモバイルアプリケーションのフレームワークであるIonicを使用しています。
- "@angular/fire": "^6.1.4"
- "firebase": "^8.3.1"
- "semver": "^7.3.5"
ionic info
コマンドの実行結果
$ ionic info Ionic: Ionic CLI : 6.11.8 (/usr/local/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/angular 5.6.0 @angular-devkit/build-angular : 0.1101.4 @angular-devkit/schematics : 11.1.4 @angular/cli : 11.1.4 @ionic/angular-toolkit : 3.1.0 Cordova: Cordova CLI : 8.0.0 Cordova Platforms : none Cordova Plugins : no whitelisted plugins (1 plugins total) Utility: cordova-res : not installed native-run : not installed System: ios-deploy : 1.9.2 ios-sim : 6.1.2 NodeJS : v12.13.1 (/usr/local/bin/node) npm : 6.14.12 OS : macOS Catalina Xcode : Xcode 12.0.1 Build version 12A7300
環境構築
環境構築をしていきます。Firebaseのプロジェクトを作成した後、今回はWebアプリを作成するため、プラットフォームのウェブのアプリを追加します。
続いて、プラットフォーム「ウェブアプリ」のSDKスニペットのfirebaseConfig
の内容をAngular(Ionic)プロジェクトのsrc/environments/environment.ts
に転記します。
AngularからFirebaseに接続する用途のライブラリである、AngularFireをnpmインストールします。
今回作成しているアプリはAngular CLIから作ったプロジェクトではなく、AngularベースのIonicプロジェクトであるため、公式が推奨しているng add
コマンドではなく、下記のコマンドを使用します。
npm i firebase @angular/fire
app.module.ts
のimports: []
にAngularFireModule.initializeApp(environment.firebaseConfig)
を追加します。
app.module.ts
import { AngularFireModule } from '@angular/fire'; import { environment } from 'src/environments/environment'; @NgModule({ // ...省略 imports: [ // add this AngularFireModule.initializeApp(environment.firebaseConfig), ], }) export class AppModule {}
強制バージョンアップメッセージの表示判定に使用する、セマンティック バージョニングを比較することができるライブラリ、node-semverもインストールします。
npm i semver
補足
今回はブラウザ上でしかアプリを動かさないので使えませんが、モバイルアプリ(iOS/Android)としても動かすときは、アプリバージョンを取得するライブラリであるcordova-plugin-app-versionを使ったりします。
ionic cordova plugin add cordova-plugin-app-version npm i @ionic-native/app-version npm i @ionic-native/core
Realtime Databaseのデータ構造を構築する
Realtime Databaseのデータ構造をJSONファイルとして作成します。
今回は、メンテナンスと強制バージョンアップのポップアップを表示したいので、下記のような構造のJSONファイルにしました。
{ "maintenance": { "maintenanceFlg": false, "message": "メンテナンスのため一時サービスを停止しております。<br/>しばらくお待ちください。", "title": "メンテナンス" }, "version": { "message": "最新版のアプリがリリースされました。<br/>バージョンアップをお願いいたします。", "minimumVersion": "0.0.3", "title": "バージョンアップ" } }
上記で作成したJSONファイルをRealtime Databaseにインポートします。
JSONファイルをインポートすると、下記画像のように、Realtime Database上にデータ構造が作成されることを確認できます。
メンテナンスと強制バージョンアップのポップアップを表示する
作成したRealtime Databaseのデータ構造を使って、ポップアップを表示するサービスクラスVersionCheckService
を作成していきます。
src/app/services/version-check.service.ts
import { Injectable } from '@angular/core'; import { AngularFireDatabase } from '@angular/fire/database'; import { Observable } from 'rxjs'; import { Maintenance } from '../model/maintenance.model'; import { Version } from '../model/version.model'; import * as semver from 'semver'; import { AlertController } from '@ionic/angular'; @Injectable({ providedIn: 'root', }) export class VersionCheckService { // このアプリのバージョン private readonly appVersion = '1.0.0'; private maintenance$: Observable<Maintenance>; private version$: Observable<Version>; private maintenanceAlert: HTMLIonAlertElement; private versionUpAlert: HTMLIonAlertElement; constructor( private db: AngularFireDatabase, private alertController: AlertController ) {} /** * 初期設定 * * @memberof VersionCheckService */ public initSetting(): void { // Realtime Databaseからデータを取得 this.maintenance$ = this.db .object<Maintenance>('maintenance') .valueChanges(); this.version$ = this.db.object<Version>('version').valueChanges(); this.maintenance$.subscribe( async (maintenance: Maintenance) => await this.checkMaintenance(maintenance) ); this.version$.subscribe( async (version: Version) => await this.checkVersion(this.appVersion, version) ); } /** * メンテナンスポップアップを表示する。 * * @private * @param {Maintenance} maintenance * @returns {Promise<void>} * @memberof VersionCheckService */ private async checkMaintenance(maintenance: Maintenance): Promise<void> { if (!maintenance) { return; } if (!maintenance.maintenanceFlg) { // メンテナンスフラグがOFFだったら処理を中断する if (this.maintenanceAlert) { // メンテナンスメッセージが開かれている場合は閉じる await this.maintenanceAlert.dismiss(); this.maintenanceAlert = undefined; } return; } // メンテナンスメッセージを表示する this.maintenanceAlert = await this.alertController.create({ header: maintenance.title, message: maintenance.message, backdropDismiss: false, // 背景をクリックしても閉じない }); await this.maintenanceAlert.present(); } /** * 強制バージョンアップメッセージを表示する。 * * @private * @param {string} appVersion * @param {Version} version * @returns * @memberof VersionCheckService */ private async checkVersion(appVersion: string, version: Version) { if (!version || !version.minimumVersion) { return; } if (semver.gte(appVersion, version.minimumVersion)) { // 最低バージョンよりもアプリのバージョンが高かったら処理を中断する if (this.versionUpAlert) { // 強制バージョンアップメッセージが開かれている場合は閉じる await this.versionUpAlert.dismiss(); this.versionUpAlert = undefined; } return; } // 強制バージョンアップメッセージを表示する this.versionUpAlert = await this.alertController.create({ header: version.title, message: version.message, backdropDismiss: false, // 背景をクリックしても閉じない }); await this.versionUpAlert.present(); } }
メンテナンスメッセージ用のクラスを作成します。
src/app/model/maintenance.model.ts
export interface Maintenance { maintenanceFlg: boolean; message: string; title: string; }
強制バージョンアップメッセージ用のクラスを作成します。
src/app/model/version.model.ts
export interface Version { message: string; minimumVersion: string; title: string; }
最後にAppComponent
からVersionCheckService
からinitSetting()
を呼び出してあげれば実装は終了です。
src/app/app.component.ts
// ...省略 export class AppComponent implements OnInit { constructor(private versionCheckService: VersionCheckService) {} public ngOnInit(): void { this.versionCheckService.initSetting(); } }
動作確認
上記で作成したコードの動作確認をします。
メンテナンスメッセージの表示
Realtime Database上のmaintenanceFlg
をtrue
に書き換えると、アプリ上でメンテナンスメッセージが表示されます。
強制バージョンアップメッセージの表示
アプリのバージョン(1.0.0
)よりも大きいバージョンを、Realtime Database上のminimumVersion
に上書くと、アプリ上で強制バージョンアップメッセージが表示されます。
参考サイト
データベースを選択: Cloud Firestore または Realtime Database | Firebase
GitHub - angular/angularfire: The official Angular library for Firebase.
App Version - Ionic Documentation
GitHub - npm/node-semver: The semver parser for node (the one npm uses)
The target entry-point -has missing dependencies: - Ionic Native - Ionic Forum
TypeScript eqの例、semver.eq TypeScriptの例 - HotExamples