20
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Firestoreでフォロー機能を作るにはどのようなdb設計をすればいいのか

Last updated at Posted at 2021-01-02

今回は、Firestoreを使ってフォロー機能を作る際にどんなdb設計にすればいいのかを紹介します。

Railsなどでフォロー機能を作る方法はいい記事が多く、それらを見ればいいのですが、NoSQLでのフォロー機能に関してそんなに記事がなかったので今回記事を書こうと思いました。

ちなみに普通のdbでのフォロー機能の設計でとても参考になる記事を紹介するなら以下の記事です。めちゃくちゃわかりやすいです。

【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】🎸

フォロー機能の使い道

まず、今回僕が作成したアプリは各ユーザーが記事を投稿できるもので、フォローしたユーザーの投稿が一覧に表示されます。(Twitterみたいな感じです)

db設計

まず、フォロー機能を作るにしてもユーザーがいないと始まらないので、usersコレクションがあります。

それから、記事を管理するpostsコレクションがあります。
ここまでは普通ですね。

ここから本題のフォロー機能なのですが、Firestoreの場合、中間テーブルを作ってリレーションのようなことができません。

そこで、followsコレクションをルートの階層(postsやusersと同じ階層)に作成します。

なぜルートの階層?

ルートの階層に作ると、後々色々なデータのやりとりやがしやすくなったり、読み取り回数が抑えられたりします。 userのデータのサブコレクションに保存するという方法もありますが、Firestoreではusersコレクションを読み取るたびにそのサブコレクションまで読み取ってしまいます。つまり、フォローの情報が全く関係ない読み取り(例えばuserの名前を表示するだけとか、userのidを取得するだけとか)を行いたいだけなのに、サブコレクションまで取得してしまい、読み取り回数up→コストがかかるということになります。

そこで、ルートの階層にfollowsコレクションを作ることで、フォローしているフォローされているといった情報を持たせ、必要な時に必要な分だけデータを取得しようといった意図があります。

dbの中身はどうなっているのか

followsコレクションの各ドキュメントの中身は以下のようになります。

フィールド名
following_uid (任意のidなど)
followed_uid (任意のidなど)
id (任意のidなど)
  • following_uid:フォローしている人のuid
  • followed_uid:フォローされている人のuid
  • id:ドキュメントのidを保存

こんな感じです。これだけではわかりにくいので、例を挙げます。

例えば、uidが1の人がuid2の人をフォローするというアクションをするとするなら、followsコレクションに保存されるデータは以下のようになります。

フィールド名
following_uid 1
followed_uid 2
id (任意のidなど)

uidが2の人がuid1の人をフォローするであれば、

フィールド名
following_uid 2
followed_uid 1
id (任意のidなど)

となります。

フォローするという一つの行動に対して1つのドキュメントが作成されます。「これって、フォローが起きるたびにデータ増えていくけどどうなの?」と初めは思いましたが、NoSQLはこれが正解っぽい(?)です。

firestoreでの多対多については、以下の記事でわかりやすくメリットデメリットを紹介されています。

Cloud Firestoreを実践投入するにあたって考えたこと

ここまで説明してきたように、rootの階層にfollowsコレクションを作ることで、タイムライン(フォローしてるユーザーの記事が表示される)を作るのであれば、followsコレクションからログインしているユーザーのuidをfollowing_uidに持つデータを

db.collection("follows")
.where("following_uid", "==", ログインしてるユーザのuid)

で取得しておいて、そのfollowed_uidとマッチする投稿を検索して表示するといった感じでできます。(投稿一つ一つにuidを持たせる必要がありますが)

以上です。

参考

【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】🎸

Cloud Firestoreを実践投入するにあたって考えたこと

【Firebase】Cloud Firestoreのデータ構造の決め方をFirebaseの動画から学ぶ

20
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?