FlutterFlow でフォロー機能を作ってみる

FlutterFlowでのフォロー機能の実装方法をまとめておきます。中間テーブルの理解が難しいかもと思ってますが、画像多めで解説していきます。

とりあえず、完成形はこんな感じ👇

https://twitter.com/kinari_kuramoto/status/1578003127109754880?s=20&t=II90-c7UlIbm3N7pIuYOVA

# 前提

- ベースのUIは既にできてるものとして進めます。フォローとフォロー解除ボタンの二つをStackで重ねておきましょう。
- User詳細ページには、任意のUserのDoc ReferenceがPage Parameterとして渡されているものとします。



# Firestore データベース設計

まずは、データベースの設計をしていきます。

フォロー機能では、”〇〇さんが□□さんをフォローしてるorしてない”という情報をデータベースの中に記述していく必要があります。今回は、UserとUserのフォロー関係を記述するための中間テーブルを作成し、そこにデータを記述していきます。

フォロー機能の他にもテーブル同士の多対多の関係性について記述する場合には同様に中間テーブルを作成するのが良いでしょう。

というわけで、左側パネルからFirestoreのタブを開いて、`friends`コレクションを作成し、

`follower` : フォローしたユーザー
`followee` : フォローされたユーザー

をフィールドにそれぞれ追加します。いずれもデータタイプは`Document Reference > Users`にしてください。
※ `Is List?`にチェックをつける必要はありません。ご注意を。
![20221016_105352.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919461/9b421bf7-a7cf-71a0-1e0a-7f655ca2e32b.jpeg)
followerとfolloweeはどちらもデータタイプがDoc Reference (Users)で、かつ名前も似ちゃうので、どっちがどっちか分からなくならないようお気をつけください。

このテーブルにおいて、follower = ”〇〇さん” かつ followee = “□□さん”となるようなレコードが存在するorしないによって、〇〇さんが□□さんをフォローしてるorしてないという状態を定義します。

や、ややこしい。。



# クエリの設定

次は、特定のfriendsレコードの有無によって、ボタンの表示(Visibility)やアクションの切り替えを行います。その前に、ボタンが”特定のfriendsレコード”にアクセスできるように予めクエリを設定しておく必要があります。

今回はフォロー/フォロー解除ボタンの親要素にあたるStackに対して、クエリを設定します。Stackをクリックして、右側パネルのBackend Queryタブを開きます。
![20221016_105408.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919461/91172146-2a6c-f625-7933-61c3c31733fd.jpeg)
クエリ設定手順
1. `Query Type`は**Query Collection**を選択。
2. `Collection`は**friends**を選択。
3. その下の`Query Type`はList of Documentsを**Single Document**に変更。
4. `Hide Widget If No Match`を**オフ**に変更。
5. フィルター(**follower = Authenticated User > User Reference**)を追加。
![20221016_105412.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919461/26183bc2-8578-da00-6945-4961130b34f1.jpeg "画像1")
6. フィルター(**followee = users Document > Reference**)を追加。
![20221016_105416.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919461/616f7ce8-a109-9a53-718d-757b8562ec68.jpeg "画像2")

一層ややこしい感じになってきましたね。5.と6.で設定したフィルターによって、friendsレコードは**一つだけ**取得されることになります。このレコードがあればフォローしてる、なければフォローしてないという形でフォロー状態を定義します。


# Visibilityで表示切り替え

フォロー状態によって、フォローボタンとフォロー解除ボタンの表示の切り替えを行います。

それぞれのボタンのPropertiesタブを開いて、`Conditional Visibility`をオンにします。クエリの設定が正しく出来ていれば、friends Documentが表示されると思うので、`friends Document > Document Exists`を選択します。

フォローボタンでは、`Apply Opposite Statement`を**オン**にしてください。
![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919461/8a98c12e-6477-70f2-166c-ff014d623c8f.png)

フォロー解除ボタンでは、`Apply Opposite Statement`を**オフ**のままにしてください。
![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919461/17814129-4eb2-ad8f-9e80-48774a8bbdca.png)


# アクションを追加


フォローボタンとフォロー解除ボタンにそれぞれアクションを追加します。それぞれのボタンのActionsタブを開いて、`+ Add Action`をクリックします。

フォローボタンでは、friendsレコードを作成します。`Database > Create Document`と選択し、Collectionでfriendsを選択してください。`+ Add Field`から、followerとfolloweeを追加し、
`follower`には、**Authenticated User > User Reference**を
`followee`には、**users Document > Reference**をそれぞれ設定してください。
![20221016_105429.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919461/f67e9659-f2b8-ffa0-443a-9ac3947384f7.jpeg)

フォロー解除ボタンでは、friendsレコードを削除します。`Database > Delete Document`と選択し、**friends Document > Reference**を選択してください。
![20221016_105433.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919461/8365160f-8a64-4fd4-5e01-d1d0f3f12814.jpeg)
これで完成です！！`Run`して動作確認してみてください。

# まとめ

手順は以下
- データベース設計
- クエリの設定
- Visibilityで表示切り替え
- アクションを追加

難しいのは、やはり中間テーブルの理解と、クエリの設定で出てきたフィルターの辺りかなと。何度か見直してもらいつつ、やってみていただければと思います。

そもそもの中間テーブルの概念についてもう少し、という方はググるとたくさん出てくるので、参考にしてください。👇一例です。

https://qiita.com/ramuneru/items/db43589551dd0c00fef9#:~:text=%E4%B8%AD%E9%96%93%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%A3%E3%81%A6%EF%BC%9F,%E3%81%9F%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%82%92%E6%8C%87%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

というわけで、ここまでありがとうございました。一人でも多くの方の参考になれば幸いです。ご意見・ご質問あればコメントからよろしくお願いします。😊


# おまけ

中間テーブルを作る方法を試す前に、UserテーブルにfollowerとfolloweeのDoc Referenceをリスト形式でプロパティとして持たせる方法を👇こちらの記事を参考にやってみたんですが、

https://community.flutterflow.io/c/discuss-and-get-help/friends-follow-unfollow-how-to-guide

以下のように一度ページ開き直さないと、Visibilityが反映されない状態になってしまいました。こっちの方法でボタンの表示の切り替えを可能にするやり方をご存知の方は教えてください🙇‍♂️

https://twitter.com/kinari_kuramoto/status/1578010404130676736?s=20&t=rsSK-KcXoF2mI_kVmWDvoA