JavaScriptでFirebaseを使ってみる


コード：https://github.com/mo49/firebase_test


## Firebase console

Googleアカウントでログイン
https://console.firebase.google.com/

## Firebase CLI

以下を参考に、プロジェクト作成までを行う
https://firebase.google.com/docs/cli/?hl=ja

プロジェクト自体はFirebase consoleで作っておいたほうがシンプル
（CLIではプロジェクトを選択するだけにする）

## ローカルで起動させる

```
$ firebase serve
```

## データベースのルール変更

親の階層のルールが子へとカスケードされる書き方

```javascript:database.rules.json
{
  "rules": {
    ".read": "true",
    "message": {
      ".write": "auth != null"
    },
    "info": {
      ".write": "true"
    }
  }
}
```

「データベース/messageの書き込みには認証が必要」
「データベース/infoの書き込みには認証が不要」という設定

## 書き込み・読み込み

### 書き込み

```javascript:set
const databaseRef = firebase.database().ref();
// set
databaseRef.set()
```

### 読み込み

パスデータの変更をvalueイベントでリッスンする

```javascript:read
// on
databaseRef.on('value',snapshot => {
  console.log(snapshot.val());
})
// once（1回のみ）
databaseRef.once('value').then(snapshot => {})
```

> 参考
https://firebase.google.com/docs/database/web/read-and-write


### リアルタイムにテキストの変更を反映する

```javascript
const $input = document.querySelector('#input')
const $output = document.querySelector('#output')

const db = firebase.database();
// データベース/messageへの参照を作成
const messageRef = db.ref('/message');

// write
$input.addEventListener('input', e => {
  messageRef.set(e.target.value);
})

// read
messageRef.on('value',snapshot => {
  $output.textContent = snapshot.val();
})
```

Firebase consoleの「Database > データ」にリアルタイム反映される

![スクリーンショット 2017-07-26 17.45.48.png](https://qiita-image-store.s3.amazonaws.com/0/136286/a86a273c-974f-20e4-d88e-1251de4139fa.png "スクリーンショット 2017-07-26 17.45.48.png")


## 認証

### サインイン・サインアウト

```javascript:サインイン
// どの認証手段を使うか
const provider = new firebase.auth.GoogleAuthProvider();

$signin.addEventListener('click', () => {
  // 指定したproviderのサインイン画面に飛ぶ
  firebase.auth().signInWithRedirect(provider);
})
```

ここではGoogleアカウントで認証
https://firebase.google.com/docs/auth/web/google-signin?hl=ja
^ 他アカウントでの認証も載っているので参考に！

```javascript:サインアウト
$signout.addEventListener('click', () => {
  firebase.auth().signOut().then(() => {
    location.reload()
  })
})
```

### 変更をリッスン

https://firebase.google.com/docs/auth/web/manage-users?hl=ja

```javascript
firebase.auth().onAuthStateChanged(user => {
  if (user) {
    const $profile = document.querySelector('#profile')
    $profile.innerHTML = `
      <div>uid: ${user['uid']}</div>
      <div>displayName: ${user['displayName']}</div>
      <div>email: ${user['email']}</div>
      <img src="${user['photoURL']}" width="100">
    `
  } else {
    // 認証していない場合は自動的に認証画面へ
    // firebase.auth().signInWithRedirect(provider);
  }
})
```

## データの操作

https://firebase.google.com/docs/database/admin/save-data?hl=ja

### child

以下の3つは同じ意味。`child`を使うとシンプルになるよという話。
(以降、infoRefを使用)

```javascript
const infoRef = db.ref('/info');
infoRef.child('user01').set({
  name: 'user01',
})
```

```javascript
const infoRef = db.ref('/info');
infoRef.set({
  user01: {
    name: 'user01',
  }
})
```

```javascript
const infoRef = db.ref('/info/user01');
infoRef.set({
  name: 'user01',
})
```


### 更新 | update

`set`:書き込む
`update`:変更があれば更新

```javascript:update
// それぞれのメソッドでpromiseが返ってくるので、
// thenで処理をつなぐこともできる
infoRef.update()
  .then((value) => {
    console.log('更新完了');
  })
  .catch((err) => {
    console.log(err.message);
  })
```

### 追加 | push

重複することのないユニークなキーを生成するので、
何度クリックしても別データとして追加されていく

```
$push.addEventListener('click', () => {
  infoRef.push({
    description: `your number is ` + Math.random() * 100,
  })
})
```

![スクリーンショット 2017-07-27 16.51.48.png](https://qiita-image-store.s3.amazonaws.com/0/136286/432987c0-ec4e-9dfb-9da0-aa0fe418ca11.png "スクリーンショット 2017-07-27 16.51.48.png")


### 削除 | remove

```javascript
infoRef.remove();
```

```javascript
infoRef.set(null);
```

## デプロイ

```
$ firebase deploy
```


> 参考
[一から始めるFirebase](https://app.codegrid.net/series/2017-firebase-basic)