Ionic + Firebaseで記録するカレンダーアプリを作る　その3 Firebaseにイベントを追加し取得

#完成イメージ
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">こんな感じ。 <a href="https://t.co/CvOFjFq2th">pic.twitter.com/CvOFjFq2th</a></p>&mdash; げん げんと (@gento34165638) <a href="https://twitter.com/gento34165638/status/1190431795877007362?ref_src=twsrc%5Etfw">November 2, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#はじめに

環境は以下の通り
・ionic4
・Nativeとの橋渡しには[capacitor](https://capacitor.ionicframework.com)を使用
・カレンダーについては[ionic2-calendar](https://github.com/twinssbc/Ionic2-Calendar#readme)というライブラリーを使用

前回は実機でのテストを行った。
:point_right:前回の記事は[こちら](https://qiita.com/kokogento/items/6ab47e05ea1e329ff6bc)

#Firebaseの設定

[こちら](https://qiita.com/Yamamoto0525/items/437a2884c0c51f5a3af8)を参考にやっていく。

##ライブラリを入れる

プロジェクトフォルダ内で

```terminal
npm install firebase @angular/fire
```

これでプロジェクトにFirebaseを導入できた。

##Firebase側でプロジェクト作成

1. [Firebase console](https://console.firebase.google.com/)に行く
2. プロジェクトを新規作成。
3. 作成したプロジェクトに**webアプリ**を追加
<img width="442" alt="スクリーンショット 2019-10-08 16.21.03.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/0608cbfe-c38c-fe66-15ae-ff1c51893cda.jpeg">

4. Firebaseプロジェクトの設定情報を取得
こんな感じの情報があるかと。`config`の中身が必要な情報だ。この画面を開いたまま、**ionicのプロジェクト**に戻ろう。
<img width="666" alt="スクリーンショット 2019-10-14 20.50.49.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/faf60955-caaa-0332-f132-5d47b47d1b83.jpeg">

**※`messagingSenderId`の下に`appId`が追加されているかもしれない**

5. データベースをテストモードで開始。
<img width="362" alt="スクリーンショット 2019-10-14 22.05.35.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/abd04e3e-1585-64c1-4475-90b3c35e4e62.jpeg">




#ionicプロジェクトにFirebase情報を入れる

##environmentファイルに追加
`src/environments/environment.ts`を開く

```typescript:environment.ts
export const environment = {
  production: true,
  firebase: {
   apiKey: "YOUR_API_KEY",
   authDomain: "YOUR_AUTH_DOMAIN",
   databaseURL: "YOUR_DATABASE_URL",
   projectId: "YOUR_PROJECT_ID",
   storageBucket: "YOUR_STORAGE_BUCKET",
   messagingSenderId: "YOUR_SENDER_ID"
   appId: "YOUR_APP_ID"
  }
};
```

`firebase`という名の変数の中に、情報を入れる

ちなみに、デフォルトで作成される環境ファイルのenvironment.prod.tsを**prod環境用（つまり本番用の環境？）**、environment.tsを**dev環境用（開発時の環境）**とされてるらしい。。

##app.moduleにenvironment情報を入れる

`app.module.ts`を以下のように変更。

```typescript:app.module.ts
import { NgModule, LOCALE_ID } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

//カレンダー関係
import { NgCalendarModule  } from 'ionic2-calendar';
import { registerLocaleData } from '@angular/common';
import localeJa from '@angular/common/locales/ja';

//Firebaseを利用するためのモジュール
import { AngularFireModule } from '@angular/fire';
import { AngularFirestoreModule } from '@angular/fire/firestore';
import { AngularFireAuthModule } from '@angular/fire/auth';

//Firebase設定情報ファイルをインポート
import { environment } from '../environments/environment';

registerLocaleData(localeJa);


@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    NgCalendarModule,
    AngularFireModule.initializeApp(environment.firebase, 'myCarendar'),
    AngularFirestoreModule,
    AngularFireAuthModule
  ],
  providers: [
    StatusBar,
    SplashScreen,
    NativeStorage,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    { provide: LOCALE_ID, useValue: 'ja-JP' }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}
```


`AngularFireModule `は言うならば**Firebase本体**。

`AngularFirestoreModule`はFirebase本体の中にある機能の１つである、データベース**Cloud Firestore**の事。

`AngularFireAuthModule `は今後の**ユーザー認証**（ログインとか）に使う機能の事。


```typescript
//Firebaseを利用するためのモジュール
import { AngularFireModule } from '@angular/fire';
import { AngularFirestoreModule } from '@angular/fire/firestore';
import { AngularFireAuthModule } from '@angular/fire/auth';
```

これで使う準備は完了。ふぅ。。




#カレンダーにイベントを追加

適当にカレンダーの上にボタンを作る。

```html:home.page.html
<ion-header>
  <ion-toolbar color="primary">
    <ion-title>
      {{ viewTitle }}
    </ion-title>
    <ion-buttons slot="end">
      <ion-button (click)="today()">Today</ion-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content padding>
<ion-button (click)="addNewEvent()">イベント追加</ion-button>

  <calendar
  [eventSource]="eventSource" 
  [calendarMode]="calendar.mode" 
  [currentDate]="calendar.currentDate"
    (onCurrentDateChanged)="onCurrentDateChanged($event)" 
    (onEventSelected)="onEventSelected($event)" 
    (onTitleChanged)="onViewTitleChanged($event)"
    (onTimeSelected)="onTimeSelected($event)"
     step="30">  
  </calendar>
</ion-content>
```

`addNewEvent`を書いて、データベースにイベントを追加させる。

```typescript:home.page.ts
import { Component } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';


@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  eventSource = [];
  viewTitle;
  selectedDate = new Date();
  calendar = {
    mode: 'month',
    currentDate: new Date(),
    locale: 'ja-JP'
  };

  constructor(
    private db: AngularFirestore,
) { }

  onViewTitleChanged(title) {
    this.viewTitle = title;
  }

  // 選択した日付を取得
  onTimeSelected(ev) {
    this.selectedDate = ev.selectedTime;
  }

  today() {
    this.calendar.currentDate = new Date();
  }

  async onEventSelected() {
    console.log('onEventSelected');
  }

  eventSelected(event) {

  }


  onCurrentDateChanged(event: Date) { }

}

addNewEvent() {
    let start = this.selectedDate;
    let end = this.selectedDate;
    end.setMinutes(end.getMinutes() + 60);

    let event = {
      title: 'イベント' + start.getMinutes(),
      startTime: start,
      endTime: end,
      allDay: false
    };
    console.log(event);
    this.db.collection(`events`).add(event);
  }
```

これでイベント追加ボタンを押した後Firebaseのデータベースを見ると、`events`というコレクションの中にイベントのドキュメントが入っているかと。

**「コレクション」と「ドキュメント」の意味がわからない場合は、Cloud Firestoreのデータモデルを知ろう。**詳しくは[こちら](https://firebase.google.com/docs/firestore/data-model?hl=ja)


#イベントを取得してカレンダーに表示
`home.page.ts`のconstructorに以下を追加。

```typescript:home.page.ts
 constructor(
    private db: AngularFirestore,
) { 
         this.db.collection(`events`)
          .snapshotChanges()
          .subscribe(colSnap => {
            this.eventSource = [];
            colSnap.forEach(snap => {
              const event: any = snap.payload.doc.data();
              event.id = snap.payload.doc.id;
              event.startTime = event.startTime.toDate();
              event.endTime = event.endTime.toDate();
              this.eventSource.push(event);
            });
          });
 }
```

とりあえずこれでカレンダーにイベントが表示されるのではないだろうか？



#最後に
続き:point_down:
[その4 dayページからイベントを追加](https://qiita.com/kokogento/items/c1c3c78db5a6e58f8a08)

各ストアで配信されてます。
興味があれば使ってみてください。:relieved:

<a href="https://apps.apple.com/jp/app/%E6%80%A7%E6%B4%BB%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC/id1484151444?mt=8">Apple Store</a>

[Google Play](https://play.google.com/store/apps/details?id=com.hCalendar.app)