当記事は公開されてから 3 年以上経過している記事です。

「Firestoreに移行したら色々と楽になった話」の改善提案など気軽にご協力いただければ幸いです。

Issue はこちらでよろしくお願いします: https://github.com/jiyuujin/webneko-blog/issues

Firestoreに移行したら色々と楽になった話
12/7/2018
Firebase
Firestore

Nuxt Adminとは

当ブログの問い合わせを管理するため、裏側の管理画面を自作、バックエンドに Firestore を採用。

ちなみに管理画面のフロントエンドでも Vue.js のフレームワークのひとつ Nuxt.js を採用。

https://admin.nekohack.app/

ただし自分以外触れません

近く権限を追加した上で、閲覧用アカウントの開設を検討中。

  1. 技術ネタ・勉強会スライド一覧
  2. Qiita 一覧(いいね管理をスマートに)
  3. 当ブログ解析結果一覧
  4. 搭乗ログ一覧

前回のおさらい

技術スタックに Nuxt (Vuetify) + Firebase、今回 SPA(generate)としてデプロイしています。フロントの話は Nuxt.js Advent Calendar 21日目 にてご紹介します。

今回の結論

DB 設計楽チン、ですがどこか無法地帯な印象の Realtime DB。より構造化された Firestore に移行することで解決する課題も多々存在しました。また多彩な型のサポートの登場も大きく、文字列や数値、バイナリやタイムスタンプ、地理的位置などが登場しています。

  1. 型のサポート
  2. 苦しんだソートの実装

対比しながら確認します

初期設定に大差はありません。予めプロジェクト ID など必要な設定を忘れないようにします。

// Realtime DB
const adminDB = Admin.database();

// Firestore
const adminFirestore = Admin.firestore();
adminFirestore.settings({
  timestampsInSnapshots: true
});

インポートの指定先に注意、Firestore に移行するので firebase/firestore を指定します。この時 firebase/app を指定してあげないと gRPC 関連のエラーに引っ掛かります。

// Realtime DB
import firebase from 'firebase'

// Firestore
import firebase from 'firebase/app'
import 'firebase/firestore'

取得処理では、 Realtime DB で苦しむ「降順」を楽に実現。

// Realtime DB
tipsRef.orderByChild('time')

// Firestore
tipsCollection.orderBy('time', 'desc').get()
    .then(snapshot => {
      let result = {
        item: []
      }
      snapshot.forEach(doc => {
        // console.log(doc.id + ' ' + doc.data())
        result.item.push({
          id: doc.id,
          data: doc.data()
        })
      })
      commit('setTips', result)
    })

個人的に更新処理が凄く分かり易くなった、という印象です。コレクションで指定のデータベースを、またドキュメントで指定のキーを特定した上で更新します。

// Realtime DB
let updates = {};
updates['/tips/' + key] = {
    title: data.title,
    url: data.url,
    description: data.description,
    tags: data.tags,
    event: data.event,
    time: data.time
  };
Admin.database().ref('tips').update(updates);

// Firestore
Firestore.firestore().collection('tips').doc(key).set({
    title: data.title,
    url: data.url,
    description: data.description,
    tags: data.tags,
    event: data.event,
    time: data.time
  });
(2621 characters)

あわせてよみたい..