この記事はAngular+Firebaseでチャットアプリを作るのエントリーです。
前記事:Firebaseの環境構築
次記事:Angular+Cloud Firestore(CREATE, READ, UPDATE, DELETE)を実装する
この記事で行うこと
本稿では、Angularのプロジェクトに「angularfire」というライブラリを使ってFirebaseの導入を行います。
angularfireとは
Angularで使い勝手がよくなるようラッピングされた、Firebaseクライアントです。
RxJSを使ってクライアントとFirebase間の同期を行うのが特徴で、現在(2018年9月)のところCloud Firestore、Realtime Database、Authentication、Cloud Storage、Firebase Messaging、Cloud Functions、Analyticsをサポートしています。公式でも紹介されています。
(2018/1追記)RTDBの記述を現時点で最新のものに差し替えました。
(2018/9追記)angularfireが対応したのでFirestoreの記述に差し替えました。
(2020/6追記)現時点(2020年6月)での最新の内容に書き換えています。
実装内容
angularfireとfirebaseをインストール
まずはプロジェクトにangularfireとfirebaseをインストールします。
cd 自分のプロジェクト
ng add @angular/fire@next
Please select a project:
> NgChat (ngchat-xxx)
(2020/06追記)このコマンドはfirabaseの公式とangularfireの公式で異なっていました。テストする際は実行時のangularfire公式を確認してください。
インストールが完了したら、環境設定を行います。
Firebaseのコンソールを開き、設定>「全般」タブのなかにあるFirebase SDK snippetから「構成」を選択します。
そこに記載されている構成をコピーし、/src/environments/environment.ts
を開いて入力します。(<>になっている部分は、自分のapiKeyを入力)
// <>となっている部分は、自分のapiKeyを入力
export const environment = {
production: false,
firebase: {
apiKey: '<your-key>',
authDomain: '<your-project-authdomain>',
databaseURL: '<your-database-URL>',
projectId: '<your-project-id>',
storageBucket: '<your-storage-bucket>',
messagingSenderId: '<your-messaging-sender-id>',
appId: '<your-app-id>',
measurementId: '<your-measurement-id>',
}
};
/src/app/app.module.ts
を開いて、AngularFireModuleとenvironmentをインポートするよう記述します。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { environment } from '../environments/environment'; // 追加
import { AngularFireModule } from '@angular/fire'; // 追加
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { ChatDatePipe } from './pipe/chat-date.pipe';
@NgModule({
declarations: [
AppComponent,
ChatDatePipe
],
imports: [
BrowserModule,
AppRoutingModule,
NgbModule,
FormsModule,
AngularFireModule.initializeApp(environment.firebase) // 追加,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Angularのモジュール
Angularでは外部ライブラリやコンポーネントなどのクラスを、モジュールで管理しています。
機能単位でモジュールファイルを作成し、@NgModule
デコレータを使ってその機能モジュールに必要なライブラリモジュールやコンポーネント、サービスなどのクラスを管理しています。
@NgModule
デコレータには幾つかのプロパティがあり、それぞれの役割がここでわかるようになっています。主なプロパティは次の通りです。
@NgModule({
// そのモジュールの中で宣言されているディレクティブ(コンポーネント)とパイプを登録する
declarations: [],
// 自分のモジュールに別のモジュールを取り込む
imports: [],
// 他のモジュールでimportsに登録されるものを指定
exports: [],
// そのモジュールの中で宣言されているサービスを登録する
providers: [],
// アプリケーションのエントリポイントになるコンポーネントを指定
bootstrap: []
})
次に本プロジェクトで使用するangularfireの機能モジュールをインポートします。
今回作成するアプリでは認証とデータベースを使用するので、AngularFireAuthModuleとAngularFirestoreModuleをインポートします。
```ts:/src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { environment } from '../environments/environment'; // 追加
import { AngularFireModule } from '@angular/fire'; // 追加
import { AngularFirestoreModule } from '@angular/fire/firestore'; // 追加
import { AngularFireAuthModule } from '@angular/fire/auth'; // 追加
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { ChatDatePipe } from './pipe/chat-date.pipe';
@NgModule({
declarations: [
AppComponent,
ChatDatePipe
],
imports: [
BrowserModule,
AppRoutingModule,
NgbModule,
FormsModule,
AngularFireModule.initializeApp(environment.firebase), // 追加,
AngularFirestoreModule, // 追加
AngularFireAuthModule, // 追加
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
これでライブラリの導入は完了です。
Cloud Firestoreを導入する
ライブラリの導入がうまくいっているか、Cloud Firestoreで試してみます。
まずは/src/app/app.component.ts
を修正して、AngularFireDatabaseをDI (Dependency Injection)し、このコンポーネントでCloud Firestoreが使えるようにします。
import { Component } from '@angular/core';
import { Comment, User } from './class/chat';
import { AngularFirestore } from '@angular/fire/firestore'; // 追加
import { Observable } from 'rxjs'; // 追加
export class AppComponent {
item: Observable<Comment>; // 追加
public content = '';
public comments = COMMENTS;
public current_user = CURRENT_USER;
// DI(依存性注入する機能を指定)
constructor(db: AngularFirestore) {
this.item = db
.collection('comments')
.doc<Comment>('item')
.valueChanges();
}
// 新しいコメントを追加
addComment(comment: string) {
if (comment) {
this.comments.push(new Comment(this.current_user, comment));
}
}
}
次に/src/app/app.component.html
を修正します。
<div class="page">
<section class="card">
<div class="card-header">
NgChat
</div>
<div class="card-body">
<ng-container *ngFor="let comment of comments">
<div class="media">
<div class="media-left" *ngIf="comment.user.uid !== currentUser.uid">
<a href="#" class="icon-rounded">{{comment.initial}}</a>
</div>
<div class="media-body">
<h4 class="media-heading">{{comment.user.name}} Date: {{comment.date | chatDate}}</h4>
<div>{{comment.content}}</div>
</div>
<div class="media-right" *ngIf="comment.user.uid === currentUser.uid">
<a href="#" class="icon-rounded">{{comment.initial}}</a>
</div>
</div>
<hr>
</ng-container>
<!-- Firestoreの反映箇所 -->
<div class="media">
<div class="media-left">
<a href="#" class="icon-rounded">{{(item | async)?.initial}}</a>
</div>
<div class="media-body">
<h4 class="media-heading">{{(item | async)?.user.name}}</h4>
<div>{{(item | async)?.content}}</div>
</div>
</div>
</div>
</section>
<section>
<form class="chart-form" (submit)="addComment(content)">
<div class="input-group">
<input type="text" class="form-control"
[(ngModel)]="content"
name="comment"
placeholder="Comment" />
<div class="input-group-append">
<button class="btn btn-info" type="submit">SEND</button>
</div>
</div>
</form>
</section>
</div>
item
のデータ読み込みの際に、async
というPipeが使われています。
これはビューへ非同期で読み込む際に使用するPipeです。ここではAngularに採用されているRxjsというライブラリのObservableが利用されていますが、その詳細については別の記事で解説します。
これでクライアント側の準備が整いました。
ng serve
を使ってプロジェクトを実行すると、エラーログがコンソールに出力されます。
ERROR in The target entry-point "@angular/fire" has missing dependencies:
- firebase/app
2020年6月時点で、ng add @angular/fire@next
だけでは十分ではなく、これとは別にfirebaseのライブラリをインストールしておく必要があります。
npm install firebase --save
後はCloud Firestoreにデータを登録するだけです。
まずはデータの親となるcollection「comments」を登録します。
次に子となる「item」を登録します。
実行結果を確認できるようにするため、すべての書き込み、読み込みを許可できるようにルールを変更します。
実行結果
データベースの更新がリアルタイムでチャットに反映されるのが確認できました。
次はCloud FirestoreのCRUD(Create、Read、Update、Delete)の実装をしていきます。
ソースコード
この時点でのソースコード
※apiKeyは削除しているので、試すときは自身で作成したapiKeyを入れてください。