angularfire2を使ってみた。あとionic3でいろいろしてみた

忘れないように各程度のメモ書き程度の物なのであまり期待しないでください。
あ、ionicはデフォルトでionic4を入れるみたいなので気を付けてください。自分と友人は苦しめられました。ゆるさんからな
#バージョンまとめ
angularfire2 5.1.0
rxjs 6.3.3
ionic-angular 3.9.2
他に聞きたいバージョンがあれば質問してください
#Firebaseの処理
Firebaseのログインやデータベースとのやり取りの処理についてです。
ちなみに海外サイトの有能マンの真似事なので詳しくはよくわかってません・ｗ・
##ログインの処理
```ts
import { AngularFireAuth } from 'angularfire2/auth';

    this.afAuth.auth.signInWithEmailAndPassword(user.email, user.password)
      .then(res => {
        // Login succeed.
        if (res.user.email && res.user.uid) {
          // Go to Page.

          // display the success message.
          this.toast.create({
            message: `Welcome to APP_NAME, ${res.user.email}`,
            duration: 3000
          }).present();
        } else {
          this.toast.create({
            message: `Could not find authentication details.`,
            duration: 3000
          }).present();
        }
      })
      .catch(err => {
        // Login failed.
        this.toast.create({
          message: `Login Id and Password do not match.`,
          duration: 3000
        }).present();
      });
  }

```
##アカウント作成
```ts
import { AngularFireAuth } from 'angularfire2/auth';

    //アカウントの作成
    this.firebaseAuth
    .auth
    .createUserWithEmailAndPassword(user.email, user.password)
    .then(value => {
      //成功
      console.log('Success!', value);

    })
    .catch(err => {
      //失敗
      console.log('Something went wrong:',err.message);
    });

```
アカウント作成時に自動的にログインされるのでその後の処理は気を付けてください
##ログアウト
```ts
import { AngularFireAuth } from 'angularfire2/auth';

    this.firebaseAuth
      .auth
      .signOut();
```
##アカウントの削除
```ts

            this.firebaseAuth
            .auth
            .currentUser
            .delete()
            .then(_ => {
        
              console.log('deleted!');
                
            })
            .catch(e => {
              console.error(e);
            });        

```
##パスワード再設定メール
```
  //メールアドレス
  email: string;
    this.firebaseAuth.auth.sendPasswordResetEmail(this.email)
        .then(() => console.log('sent Password Reset Email!'))
        .catch((error) => console.log(error))
```
##Realtime Databaseにデータを入れる
```ts
import { AngularFireDatabase } from "angularfire2/database";
//UIDを作らない
this.db.object('/item').set(item);

//UID作成し、keyを取得
const key = this.db.list('item/').push('item').key;


```

##keyを含む取得
```ts
import { map } from 'rxjs/operators';
import { AngularFireDatabase } from "angularfire2/database";
import { Observable } from 'rxjs/Observable';

  //firebaseのデータの入れ子
  items: Observable<any[]>;
    //データベースからデータ取得(keyを含める)
    this.items = this.db.list('/items')
    .snapshotChanges()
    .pipe(map(items => {
      return items.map(a => {
        const data = a.payload.val();
        const key = a.payload.key;
        return {key, ...data};           // or {key, ...data} in case data is Obj
      });
    }));
```
rxjsのバージョンによってmapやObservableが見つかりません。その時はObservable not moduleとかmap not moduleと調べるとnpmコマンドを有能外国人マンが教えてくれます。すげえやあ
`items{"Keytom": "valtom"}`
このようなjsonだったとすると出力するときは

```
<!--データの受け取り-->
  <ion-list>
    <button ion-item *ngFor="let item of items | async" (click)="itemSelected()">
      {{item.key}} {{item.Keytom}}
    </button>
</ion-list>
```
これで出ると思います。結果は

```
Keytom valtom
```
となるはずです。違ったらごめんなさい。海外サイトを参考にしてください
valueだけをとる方法もありますが、angularfire2のGithubを参考にしてください。あちらのほうが分かりやすいです。
##Dateのフォーマット
```
import { DatePipe } from '@angular/common';/*app.module.tsのprovidersにも追加*/

const data = new Date();
const formattedDate = this.datePipe.transform(data, 'y/MM/dd (EE) HH:mm');
```
#特定の項目のkeyを参照してその項目の詳細を取得する
ものすごく疲れました。もっとうまいやり方があると思うのですが、自分の解決手段を乗せておきます
![a.PNG](https://qiita-image-store.s3.amazonaws.com/0/304161/48910e53-9b6f-75e8-04f0-5ce388dc60fa.png)

こういうデータがあるとします。その時は


```ts
  //リスト構造
  itemlist: any[] = new Array;
    //データベースからデータ取得(keyを含める)
    this.items = this.db.list('item/itemlist')
    .snapshotChanges()
    .pipe(map(getdata => {
      return getdata.map(a => {
        //valueを取る
        const data = a.payload.val();
        //keyをとる
        const key = a.payload.key;
        //状態を見に行く
        this.db.list('items/' + key)
        .valueChanges()
        .subscribe(item => {//よくわからんが順番に走る。止まるんじゃねえぞ...
           //連想配列に入れる
           this.itemlist.push({key: key, value: item[0]});
        });
        //keyとvalue返す
        return {key, ...data};
      });
    }));

```
valueも取りたい方向けに書いてますが、一次元配列でも大丈夫そうです。subscribeって何者？
出力方法は

```html
  <!--データの受け取り-->
  <ion-list inset>
    <button ion-item *ngFor="let item of items | async; let idx = index ">
      {{item.0001}} {{itemlist[idx]?.key }} {{itemlist[idx]?.value }}
    </button>
</ion-list>
```
です。おそらく

```
ID 0001 スパイス
```
と出るはずです。自信がないのは自分のコードとは違いすぎるからです。複雑になりすぎて参考になりません。
他にいい方法があれば教えてください
ちなみに?がなければundefinedのエラーが起こります。原因はデータを取ってくる前に出力させようとしているかららしいです。?を付けると回避できます。なんでですかね

##selectのselectedを動的にtrueにする
```html

    <ion-item *ngFor="let item of items | async">
      <ion-label>お好きなタイトルで</ion-label>
      <ion-select [ngModel]="Value" (ngModelChange)='onChange($event,item.key)'>
        <ion-option [value]="あ" [selected]="item.value == 'あ'" text-center>あ</ion-option>
        <ion-option [value]="い" [selected]="item.value == 'い'" text-center>い</ion-
      </ion-select>
    </ion-item>
```
angularの仕様かはわかりませんが、html側のイベントバインディングや[(ngModel)]の実行はコードが先に書かれている順で動きます。[(ngModel)]を後ろのほうに書いてたら奇妙なバインディングになっていました。

##tabsが残らないsetRoot
```ts

import { NavController, App } from 'ionic-angular';
constructor(public navCtrl: NavController,public app: App){}
//これか
this.app.getRootNav().setRoot(ページ);

//これで動きます。私はこれで動きました
this.navCtrl.parent.parent.setRoot(ページ);
```
これらを使ったアプリの製作は終了したのでもう増えません
では。