まえがき

この記事では、自作でチャットUIを作る方法を解説します。理解できればチャットUIを作成することは簡単なのですが、初めて自作する場合は難しい場合もあると思います。そこで、今回の記事ではUIに絞って解説していきます。ぜひ一緒に完成させましょう!

コレクションの作成

今回は、2つのコレクションと、1つのサブコレクションでチャット機能を実装する方法で進めていきます。

userコレクション

まずは、「users」のデータベースを作成していきます。

左の「Firestore」をクリックし、「+」をクリック。「users」と入力し、「create」→「Yes」をクリック。この状態で最低限のフィールドが自動的に作成されます。

chatコレクション

チャット機能は、チャットのグループを管理するコレクションと、チャット内で行われる一つ一つのメッセージを管理するコレクションの2つのコレクションが必要になります。まずはそれぞれのチャットを管理する「chars」コレクションを作成します。

画面左上の「+」をクリック。「chat」と入力し「create」をクリックします。 次に「Start from scratch」をクリックし、

Field Nameを「created_at」、Data Typeを「Date Time」を選択しチャックをクリックします。 Field Nameを「member」、Data Typeを「Document Reference」を選択し、「users」のListを選びます。

Field Nameを「last_message」、Data Typeを「String」を選択。

Field Nameを「last_sendBy」、Data Typeを「Document Reference」を選択し、「users」を選びます。

messageサブコレクション

次にサブコレクションを作成します。

まずはチャットのやり取りを行うページを作成していましょう。

画面左上の「+」をクリック→Is Sub collectionをオンにし、「chat」を選択し、「message」と入力します。 次に「Start from scratch」をクリックし、

Field Nameを「createdAt」、Data Typeを「Date Time」を選択します。 Field Nameを「text」、Data Typeを「String」を選択。 Field Nameを「sendBy」、Data Typeを「Document Reference」を選択し、「users」を選びます。

個別チャットページのUI作成

デフォルトで配置されている「Column」を削除します。 Page Parametersで、「+Add parameter」をクリックし、Parameter Nameを「chatRef」、Typeを「Document Reference」、Collection Typeを「chat」とします。

エレメントを追加

下記の画像と同じになるようにエレメントを追加していきます。デザインは後で修正していくので、まずは画像と同じ構造と同じになるように追加してください。

UIの修正

まずは、ListViewと同じ階層にある「Container」を選択し、alignmentをXが「0」Yが「1」の状態します。

画面の下部にエレメントが移動したことを確認し、hightを空白にし、widthのinfiniteのアイコンをクリックします。これで画面横幅いっぱいに広がり、高さは子要素の高さによって変動するようになりました!

次に、今位置を変更したContainerの子要素である「Row」を選択し、Paddingを 上と左方向にに、「4」、下方向に「16」つけます。

次にTextFieldを修正していきます。

「TextField」を選択し、

Input Border Typeを「outline」に、 filledのトグルスイッチをオンに Border Radiusを「24」にします。

「IconButton」を選択し、 Fill Colorを「Clea Color」 Border Colorも「Clea Color」とします。

Icon→Choose Iconで「send」と入力し、一番はじめの紙飛行機のアイコンを選択します。

ListViewを選択し、Properties Panelから、「Backend Query」を選択します。 「Add Query」→Query Typeを「Query Collection」→Collectionを「message」とします。 chat Referenceのvalue SourceをFrom でPage Parameterの「chatRef」を選択します。

Orderingで、「createdAt」を選択し、「increase」とします。

すると、ListView内の子要素がListで表示されます。

また、このListViewにも左右に「16px」のPaddingをつけます。

Listの中のRowを選択し、Cross Axis Alignmentを、左端の「Start」に変更します。 このRowの子要素である、CircleImageを選択し、Diameterを「40」に変更します。 CircleImageのProperties Panelから、「Backend Query」を選択します。

「Add Query」→Query Typeを「Document from Reference」→Collectionを「users」とし、 「message Document」の「SendBy」に設定します。

CircleImageのPathの横のアイコンをクリックし、「users Document」の「photo_url」を選択します。

Containerを選択し、 hight、widthともに空白に widthのmax widthを「75%」

Paddingを左方向に「8px」 Border Radiusを「12px」にします。

これで、最大でも画面の横幅サイズの75%までしか横に伸びず、それ以上の場合は下方向にContainerが伸びていくようになります。

今選択していたContainerの子要素である、Columnを選択し、Paddingを全方向に「12px」つけます。

最後にtextを修正していきます。

textを選択した状態で、textの横のアイコンをクリックし、「message Document」の「text」とします。

これまで作成してきたComponentは、自分以外が送信したメッセージを表示するものです。ですので、自分が投稿したメッセージが右側に表示されるようにしましょう!

Conditionの追加

Rowを選択し、visibilityのConditionalのトグルスイッチをオンにし、「unset」→

「Conditions」→「Single Condition」と進みます。

First Valueを「message Document」の「SendBy」

Not Equal to

Second Valueを「Authenticated User」の「User Reference」とします。

これで、自分以外のメッセージの場合は左側に表示されるようになりました。

自分側UIの作成

Rowを選択し、右クリックで「duplicate」をクリックします。 複製された要素のRowを選択し、Main Axis Alignmentを「End」に変更し、要素を右側にします。

CircleImageは不要なので、削除します。

Conditionの追加

Rowを選択し、visibilityのConditionalのトグルスイッチをオンにし、「unset」→

「Conditions」→「Single Condition」と進みます。

First Valueを「message Document」の「SendBy」

Equal to

Second Valueを「Authenticated User」の「User Reference」とします。

メッセージ追加アクション

紙飛行機のアイコンを選択し、アクションを追加します。

「Create Document」で、Collectionを「message」とし、chat Referenceのvalue SourceをFrom でPage Parameterの「chatRef」を選択します。

textに、Value Sourceで、Widget stateの「text Field」を選択  sendByにValue Sourceで「Authenticated User」の「User Reference」とします。

今作成したアクションの後列に、「Update Document」のアクションを追加します。

Select Reference to updateを、Page Parameterの「chatRef」を選択します。

last_sent_byに、Value Sourceで「Authenticated User」の「User Reference」とします。 last_messageに、Value Sourceで、Widget stateの「text Field」を選択します。

さいごに

この記事では、チャットUIを中心にチャット機能を解説いたしました。一見難しく見えますが、いざ実装してみると、案外簡単に作成できます!ぜひ一度自作でチャット機能を実装し、FlutterFlowの開発を進めていきましょう!