JavaScript
Angular
Firebase

AngularのプロジェクトにFirebaseを導入する


この記事はAngular+Firebaseでチャットアプリを作るのエントリーです。

前記事:Firebaseの環境構築

次記事:Angular+Cloud Firestore(CREATE, READ, UPDATE, DELETE)を実装する



この記事で行うこと

本稿では、Angularのプロジェクトに「angularfire2」というライブラリを使ってFirebaseの導入を行います。


angularfire2とは

Angularで使い勝手がよくなるようラッピングされた、Firebaseクライアントです。

RxJSを使ってクライアントとFirebase間の同期を行うのが特徴で、現在(2018年9月)のところCloud Firestore、Realtime Database、Authentication、Cloud Storage、Firebase Messaging、Cloud Functionsをサポートしています。

公式でも紹介されています。(なぜが日本語ページでは表示されない)


(2018/1追記)RTDBの記述を現時点で最新のものに差し替えました。

(2018/9追記)angularfire2が対応したのでFirestoreの記述に差し替えました。



実装内容


angularfire2とfirebaseをインストール

まずはプロジェクトにangularfire2とfirebaseをインストールします。

cd 自分のプロジェクト

npm install firebase @angular/fire --save

インストールが完了したら、環境設定を行います。

/src/environments/environment.tsを開いて、Firebaseの環境構築でメモにとっておいたapiKeyを入力します。(<>になっている部分は、自分のapiKeyを入力)


/src/environments/environment.ts

// <>となっている部分は、自分の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>'
}
};

/src/app/app.module.tsを開いて、AngularFireModuleとenvironmentをインポートするよう記述します。


/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 { AppComponent } from './app.component';
import { ChatDatePipe } from './pipe/chat-date.pipe';

@NgModule({
declarations: [
AppComponent,
ChatDatePipe
],
imports: [
BrowserModule,
FormsModule,
AngularFireModule.initializeApp(environment.firebase) // 追加
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }



Angularのモジュール

Angularでは外部ライブラリやコンポーネントなどのクラスを、モジュールで管理しています。

機能単位でモジュールファイルを作成し、@NgModuleデコレータを使ってその機能モジュールに必要なライブラリモジュールやコンポーネント、サービスなどのクラスを管理しています。

@NgModuleデコレータには幾つかのプロパティがあり、それぞれの役割がここでわかるようになっています。主なプロパティは次の通りです。

@NgModule({

// そのモジュールの中で宣言されているディレクティブ(コンポーネント)とパイプを登録する
declarations: [],
// 自分のモジュールに別のモジュールを取り込む
imports: [],
// 他のモジュールでimportsに登録されるものを指定
exports: [],
// そのモジュールの中で宣言されているサービスを登録する
providers: [],
// アプリケーションのエントリポイントになるコンポーネントを指定
bootstrap: []
})

次に本プロジェクトで使用するangularfire2の機能モジュールをインポートします。

今回作成するアプリでは認証とデータベースを使用するので、AngularFireAuthModuleとAngularFirestoreModuleをインポートします。


/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 { AppComponent } from './app.component';
import { ChatDatePipe } from './pipe/chat-date.pipe';

@NgModule({
declarations: [
AppComponent,
ChatDatePipe
],
imports: [
BrowserModule,
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が使えるようにします。


/src/app/app.component.ts

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を修正します。


/src/app/app.component.html

  <section class="card">

<div class="card-header">
NgChat
</div>
<div class="card-block">
<ng-container *ngFor="let comment of comments">
<div class="media">
<div class="media-left" *ngIf="comment.user.uid !== current_user.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 === current_user.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>
<hr>
</div>
</section>


itemのデータ読み込みの際に、asyncというPipeが使われています。

これはビューへ非同期で読み込む際に使用するPipeです。ここではAngularに採用されているRxjsというライブラリのObservableが利用されていますが、その詳細については別の記事で解説します。


これでクライアント側の準備が整いました。

ng serveを使ってプロジェクトを実行すると、エラーログがコンソールに出力されます。

これはまだCloud Firestoreが有効になっていないために表示されるエラーです。

Firebaseコンソールを開き、DatabaseページからCloud Firestoreを有効化します。

NgChat – Database – Firebase console.png

Cloud Firestoreのプロビジョニングが完了した後ng serveを実行すると、先ほどのエラーがなくなります。

後はCloud Firestoreにデータを登録するだけです。

まずはデータの親となるcollection「comments」を登録します。

NgChat – Database – Firebase console (2).png

次に子となる「item」を登録します。

NgChat – Database – Firebase console (3).png


実行結果

Sep-15-2018 17-37-23.gif

データベースの更新がリアルタイムでチャットに反映されるのが確認できました。

次はCloud FirestoreのCRUD(Create、Read、Update、Delete)の実装をしていきます。


ソースコード

この時点でのソースコード

※apiKeyは削除しているので、試すときは自身で作成したapiKeyを入れてください。