What
この記事は, 3/7(Sat) GDG Tokyo様主催の[Angular+Firebase Live Coding Session]で扱われたHands-onをまとめる.
Hands-onでは, Angularチュートリアルである[スマホ決済ECサイト]に対して, Firebaseを対応させ, アプリのホスティング, FirestoreのDB使用, FirebaseAuthによる認証, FirebaseRemoteConfigによるアプリリリース不要のアプリ文言変更などに対応させた.
Todo
- FirebaseのHostingを使ってアプリをデプロイする
- FirebaseのFirestoreを使ってFirebaseのDatabaseをリアルタイムでアプリに表示する
- FirebaseのAuthenticationを使ってGoogle Sign Inを実装する
- FirebaseのAuthenticationを使って非ログイン/ログイン状態の不整合をリダイレクトで処理する
- FirebaseのRemoteConfigを使ってリリース不要でアプリの表示文言を変更する
(RemoteConfigのWebアプリ版はbeta版)
What is this for
この記事は, 以下開催案内の記述の通りAngularとFirebase入門向け
connpass URL:
https://gdg-tokyo.connpass.com/event/168843/?utm_campaign=event_message_to_selected_participant&utm_source=notifications&utm_medium=email&utm_content=title_link
こちらはAngularとFirebaseの入門向けLive Coding Sessionとなります。
What use
扱うF/W, 機能は以下の通り.
-
Angular
-
Firebase
- Firestore
- Authentication
- Hosting
- RemoteConfig
Environment & Version
- OS: Windows10
- Angular CLI: 8.3.18
- Node: 10.16.3
Note
実装の大まかな流れ
- Angularプロジェクト生成
- Firebaseプロジェクト生成
- Firebase Consoleで機能を使えるようにする
- Angularアプリで追加したFirebaseの機能を使えるようにする(app.component.tsを編集)
- 各Component(≒ページ)のTS/HTMLを記述する
- 2~4の繰り返し
Step for reproducing
Hand-onのarchive動画は以下
初期構築
-
Angular CLI/プロジェクトの生成(下記参照)
-
Angularチュートリアル完成状態のソースをcloneする(lacolaco様のgithub)
git clone github.com/lacolaco/angularfire-20200307-starter (cd "project directory"が必要かも) npm install npm run start
-
Firebaseでプロジェクトを作る
-
FirebaseプロジェクトにWebアプリを追加
-
AngularアプリとFirebaseプロジェクトを紐づける(environmentにfirebaseConfig追加)
- Firebase Console -> メニューバーギアマーク -> プロジェクトを設定 -> 全般タブ -> マイアプリ -> Firebase SDK snippet -> 構成のsnippetをコピー
- 以下に貼り付け
const firebaseConfig = {
apiKey: ~~~
~~~中略~~~
measurementId: ~~~
};
environment定数に1行追記
export const environment = {
production: false,
firebaseConfig //←追記
};
FirebaseHostingでアプリをHostingする
- FirebaseでHosting設定をする
- Firebase Console - HostingからHostingするアプリを選択
- 以下コマンドでAngularアプリをHostingする
npm run ng deploy
🎉Hosting完了🎉 (1/5完了)
Firestoreを使ってFirebase DatabaseからAngularアプリにデータを渡す
cloneしたプロジェクトの製品(Phone XLなど)は, /src/app/product.tsを読み込んでいるだけ. Firestoreのデータベースのデータを表示するように実装する
-
FirebaseプロジェクトでDatabaseを以下のように作成/設定する
- コレクション: "products"
- ドキュメント: 自動IDでよい
- フィールド(/src/product.tsを複製する ※)
- name(string),
- price(number)
- desctiprion(string)
- id(number)
※注意※
idはproducts.tsにないプロパティだが, 後にngForでコレクションをループしてhtmlの要素を生成するためにiterableオブジェクトが必要になるため必須 -
AngularでFirestoreを利用できるようにする
- "AngularFireModule" と "AngularFirestoreModule"をimportする.
- 'fire/firestore';は現時点では書かないといけないらしい.
/src/app/app.component.tsimport { AngularFireModule } from '@angular/fire'; import { AngularFirestoreModule } from '@angular/fire/firestore'; import 'fire/firestore';
-
@NgModuleにimportした2つのモジュールを登録する
/src/app/app.component.tsRouterModule.forRoot([ ~~~中略~~~ ]), AngularFireModule.initializeApp(environment.firebaseConfig), //←追記 AngularFirebaseModule, //←追記
4.AngularFirestoreをproduct-list.componentにDependency Injectionする
- また, "valueChanges"メソッドにより, Firestoreに変更があったときにリアルタイムでアプリが変更を検知し更新するようにする.
constructor(private firestore: AngularFirestore) {}
products = this.firestore.collection('products').valueChanges();
🎉 Firestoreで変更するたびにアプリの製品情報が更新されるようになる 🎉 (2/5完了)
FirebaseAuthでGoogle認証を実装する
- FirebaseプロジェクトにFirebaseAuthでGoogleAuthProviderを使えるように設定する
- Firebase Console - Authentication - Sign-in methodタブ - Google - 有効
-
AngularアプリでFirebaseAuthを利用できるようにする
/src/app/app.component.tsimport { AngularFireAuthModule } from '@angular/fire/auth'; //←追記 ~~~中略~~~ AngularFirestoreModule, AngularFireAuthModule, //←追記
3.'/sign-in'ページを追加するために, sign-in componentを生成する
```
ng generate conponent sign-in
```
4.アプリのrouting(ページ遷移の設定)の設定をする.
RouterModule.forRoot([
{ path: '', component: ProductListComponent },
{ path: 'products/:productId', component: ProductDetailsComponent },
{ path: 'cart', component: CartComponent },
{ path: 'shipping', component: ShippingComponent },
{ path: 'sign-in', component: SignInComponent }, //←追記
ブラウザでlocalhost:4200/sign-inにアクセス
sign-inページが works!
5.signInメソッド追加
ngOnInit(): void {
}
//↓追記
signIn() {
this.auth.signInWithPopup(new auth.GoogleAuthProvider());
}
6.sign-in状態のhtmlやbuttonを実装
<div *ngIf="user | async as u; else showSignIn">
Logged in
{{ u.displayName }}
<a routerLink="/cart">Go to cart</a>
</div>
<ng-template #showSignIn>
<button (click)="signIn()">Sign in with Google</button>
</ng-template>
7.sign out機能をtop-barに実装する
(一番下にbutton要素を追加)
<button *ngIf="user | async" (click)="signOut()">
Sign out
</button>
🎉 Googleサインインが実装完了 🎉 (3/5完了)
FirebaseAuthGuardで非ログイン/ログイン状態での不整合を防ぐ
- 非ログイン状態で/cartページに遷移したら, /sign-inページにリダイレクトさせる
- ログイン状態で/sign-inページに遷移したら, /ページにリダイレクトさせる
- モジュールの追加
import {
AngularFireAuthGuardModule,
canActivate,
redirectLoggedInTo,
redirectUnauthorizedTo
} from '@angular/fire/auth-guard';
2.routingの設定
RouterModule.forRoot([
{ path: '', component: ProductListComponent },
{ path: 'products/:productId', component: ProductDetailsComponent },
//↓cartページにcanActivate関数追加
{
path: 'cart',
component: CartComponent,
...canActivate(() => redirectUnauthorizedTo(['/sign-in']))
},
{ path: 'shipping', component: ShippingComponent },
//↓sign-inページにcanActivate関数追加
{
path: 'sign-in',
component: SignInComponent,
...canActivate(() => redirectLoggedInTo(['/']))
},
]),
- canActivate関数の書き方はAngularっぽい書き方らしい
🎉 非ログイン状態で/cartページ遷移時に/sign-inページ遷移, ログイン状態で/sign-inページに遷移時に/(ルートページ)に遷移するようになる 🎉 (4/5完了)
FirebaseRemoteConfigでアプリのリリースなく, アプリ内の文言を変更する
(RemoteConfigのWebアプリ版はbeta版)
- FirebaseでRemoteConfigを設定する
- Firebase Console - Remote Config(下の方) - パラメータを追加 - 任意のパラメータキー - 値を入力(ex)Now on sale! - 条件の値を追加 - (ex)言語 - Japaneseの場合セール中です
2.モジュール追加
import {
AngularFireRemoteConfigModule,
SETTHINGS
} from '@angular/fire/remote-config';
- SETTINGSは開発用にRemoteConfigのFetch間隔を指定するために使用. 指定しない場合のFetch間隔は長いため, Fetch間隔を任意に指定できるようにする.
3.providersにSETTING定数などを記載
providers: [
{
provide: SETTINGS, //←追記
useValue: { minimumFetchIntervalMillis: 10_000 } //←追記
}
],
4.プロモーションメッセージを表示するcomponentをgenerateする
ng generate component promotion-message
5.モジュール追加
AngularFireAuthGuardModule,
AngularFireRemoteConfigModule, //←追記
6.promotion-message側の実装
constructor(private config: AngularFireRemoteConfig) {}
promotionMessage = this.config.strings['promotionMessage'];
7.テンプレート側の実装
<p *ngIf="promotionMessage | async as message">{{ message }}></p>
🎉 RemoteConfigで設定した文字列がアプリ内で表示される 🎉 (5/5完了)
最終的なコード
https://github.com/lacolaco/angularfire-20200307-starter
(lacolaco様)のfinishedブランチを参考にしました.