2018-10-31に更新

Firestoreの参照型によるリレーションを試す

FirebaseのFirestoreはNoSQLのため、コレクションの下にサブコレクションを登録するような形でデータをネストして登録していくことができます。ただ、これではRDBでやっているようなリレーションが実装できず、データが色々なところに分散してしまうため、各データを連携させる必要がある場合には非常に使いづらいです。一応リレーションもできるっぽいので、ちょっと試してみました。

※2018/8月現在、Firestoreがβバージョンのタイミングの記事となります。環境はJavaScriptです。

ちなみに、もうちょっと詳しく考察されている記事があります。

Cloud FirestoreのSubCollectionとQueryっていつ使うの問題

多分これのリレーションシップ参照型というところの話です。上記の記事ではManyToMany, hasManyあたりの話をしていると思いますが、今回試したのはbelongsToの話になります。

参照型

Firestoreに格納するデータには色々型があります。

https://firebase.google.com/docs/firestore/manage-data/data-types?hl=ja

この中を見ると「参照」という型があります。が、概念的なものが書かれているだけで、他のページを探してみても説明が見つかりません。(ただ見つけられていないだけか、βだからかは分かりません)

そのためとりあえずこれを使って1:1のリレーションができるか試してみました。

そもそも参照型と何か

データを追加するところのマニュアルを見てみると、addした後にdocRefという値が取得できています。もしかするとこれかな? と思い、別のデータを保存する際にこのdocRefをそのまま代入して保存してみました。

      // userのdocRefをそのまま入れる 
      this.post.user = this.$store.state.user;
      db
        .collection("posts")
        .add(this.post)
        .then(docRef => {
          this.posts = getPosts();
        })
        .catch(error => console.log(error));

Firebaseのconsoleで見てみるとちゃんと入っていました。

body: "aaaa"
user: /users/scQa34jZbdF2mpuVcMMV

という感じで、参照型の保存自体はこんな感じでできるようです。

リレーションデータの取得

取得までは試していません。

ざっと1ファイルで適当に試してみました。適当なので実際に組み込む時は並列処理したりもっと良い書き方ができると思います。

const firebase = require("firebase");

const config = {
};
firebase.initializeApp(config);
const db = firebase.firestore();

async function execute() {
  // ユーザーデータを登録
  const userData = {
    name: "name" + (new Date()).getTime(),
  };
  const userRef = await db.collection("users").add(userData);

  // ユーザーデータを紐づけて投稿を登録
  const postData = {
    name: "post" + (new Date()).getTime(),
    user: userRef
  };
  const postRef = await db.collection("posts").add(postData);

  // 登録したデータを全部取得
  const querySnapshot = await db.collection("posts").get();
  const posts = [];
  querySnapshot.forEach(doc => {
    posts.push(doc.data());
  });

  for (let i = 0; i < posts.length; i++) {
    // リレーションデータを取得
    const post = posts[i];
    const userQuerySnapshot = await post.user.get();
    post.userData = userQuerySnapshot.data();
  }

  return posts;
}

execute().then(posts => {
  console.log(posts);
  process.exit(0);
});

とりあえず試しに動かしたサンプルも置いておきます。

Firestore Reference data type sample

ツイッターでシェア
みんなに共有、忘れないようにメモ

だら@Crieit開発者

Crieitの開発者です。 Webエンジニアです(在宅)。大体10年ちょい。 記事でわかりにくいところがあればDMで質問していただくか、案件発注してください。 業務依頼、同業種の方からのコンタクトなどお気軽にご連絡ください。 業務経験有:PHP, MySQL, Laravel, React, Flutter, Vue.js, Node, RoR 趣味:Elixir, Phoenix, Nuxt, Express, GCP, AWS等色々 PHPフレームワークちいたんの作者

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント