【Firebase】RealtimeDatabase とFirestoreの違い 

#用途
RealtimeDatabaseでアプリ作成中なのに、ググって出てくるコードがFirestoreの時が多々あったため、 RealtimeDatabase/Cloud Firestore どちらともコードを把握しておいてスムーズにアプリ作成できるようにということで投稿


#書き込み

【RealtimeDatabase】 push()

```csharp:RealtimeDatabase

firebase.database().ref("favs").push({
        user_id: user.uid,
        post_id: post.id
      })
``` 

【Cloud Firestore】  add()/set()

```csharp:CloudFirestore

db.collection('follows').add({
       following_id: user.uid,
       follwed_id: detail_user.user_id
     })
```

■コメント
Firestoreのadd()とset()の違いは以下の通り。
①add()
addメソッドでは作成時に一意なIDを自動作成してくれます。idにアクセスしたいときは.thenを使うといいかと、、、。

```csharp:CloudFirestore
this.memoRef.add({
    id: null,
    content: this.memo
  })
  .then(doc => {
    this.memoRef.doc(doc.id).update({
      id: doc.id
    })
  })
  .catch( => {
    // error handling
  })
```

②set()
docと一緒に用いることによって、ドキュメント名を指定することができます。データを一覧として取得したいときなどに便利。
この時にdoc()←このように何も指定しないときはaddメソッドと同じように一意なidを作成します。
下のコードはFirestoreの公式ドキュメントより引用。https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja

```csharp:CloudFirestore
db.collection("cities").doc("LA").set({
    name: "Los Angeles",
    state: "CA",
    country: "USA"
})
.then(function() {
    console.log("Document successfully written!");
})
.catch(function(error) {
    console.error("Error writing document: ", error);
});
```

#1度だけデータ取り出し
【RealtimeDatabase】 once("value"),  on("value")

```csharp:RealtimeDatabase

firebase.database().ref("users").once("value")
    .then(data =>{
     console.log(data.val())     
   }
```

【Cloud Firestore】  get()

```csharp:CloudFirestore

db.collection('users').get().then((snapshot) => {
  snapshot.forEach((doc) => {
    console.log(`${doc.id} => ${doc.data()['id']}`)
  })
})
```

#変更がある場合のみ取得 / リアルタイムに取得
【RealtimeDatabase】 on('child_changed',)

```csharp:RealtimeDatabase
db.ref('messages').on('child_changed', (data) => {
  console.log(data.val())
})
```

【Cloud Firestore】   onSnapshot()

```csharp:CloudFirestore

db.collection('messsages').doc('id').onSnapshot((doc) => {
  console.log(doc.data())
})
```

#データの更新
【RealtimeDatabase/Firestore どちらも】  update

```csharp:RealtimeDatabase

db.ref().update({'name': 'Naoya Hirano'})
```
```csharp:CloudFirestore
db.collection('messages').doc('ID').update({
  name: 'Naoya Hirano'
})
```

#削除
【RealtimeDatabase】 remove()

```csharp:RealtimeDatabase
db.ref('messages').remove()
```
【Cloud Firestore】  delete()

```csharp:CloudFirestore
// 特定のドキュメントに対して
var message = db.collection('messages').doc('ID')


// 特定のフィールドに対して
var hogeFuga = hogeRef.update({
    name: firebase.firestore.FieldValue.delete()
})
```



#フィルター
【RealtimeDatabase】 orderByChild().equallTo().on("child_added", snap)

```csharp:RealtimeDatabase
const ref = firebase.database().ref("messages")
ref.orderByChild("uid").equalTo(getters.user.id).on("child_added", (snap) =>{
    snap.ref.remove()
      }
    })
```
【Cloud Firestore】   where('', '==', ).get()  +  forEach

```csharp:CloudFirestore
 db.collection('follows').where('following_id', '==', user.uid).get().then(elements => {
       elements.forEach(element => {
         console.log(element.data())
       })
     })
```

■コメント
orderByChildではforEachで配列内の要素をループするのは不要なので、入れるとエラーが出ることに注意。orderByChild以外のフィルターは下記を参照。
https://firebase.google.com/docs/database/web/lists-of-data?hl=ja
where() ではforEach必須。


#最後に
アプリ作成を進めていく中で発見したRealtimeDatabase/CloudFirestoreのコードの違いをまとめてみましたが、他にも心当たりあればコメントいただければ助かります。
他に自分で発見した箇所があれば随時更新していきます。