チャットApp(完成)
今回でチャットAppが完成です!!長かったですね!めっちゃ嬉しいんですが、落ち着いて最後にしっかり記事に残そうと思います。今回は、誰かを招待するときのURLをコピーするボタンとfirestoreのルールを設定します。
URLコピー機能
これは以前作ったプロフィールページのcreateRoomBtn関数の中にコンポーネントを作りcopyURL関数を定義します。
const copyURL = () => {
const URL = document.getElementById("roomURL").textContent;
navigator.clipboard.writeText(URL);
alert("コピー!!");
}
const createRoomBtn = () => {
if (!roomExist) {
return (
<BasicButton
fullWidth ={ true }
onclick ={ createChatroom }
>
チャットルーム作成
</BasicButton>
);
}
return (
<div>
<div className={ Styles.Roombtn }>
<BasicButton
fullWidth ={ true }
onclick ={ createChatroom }
>
チャットルーム初期化
</BasicButton>
</div>
<div>
<BasicH3>
以下のURLを教えてチャットルームに招待しよう!
</BasicH3>
</div>
<div className={ Styles.copydiv }>
<div id="roomURL" className={ Styles.url }>
<BasicParagraph>
{ location.protocol + "//" + location.host + `/chatroom/${user.uid}` }
</BasicParagraph>
</div>
<div className={ Styles.copyBtn }>
<BasicButton
fullWidth={ true }
onclick={ copyURL }
>
コピー
</BasicButton>
</div>
</div>
</div>
);
}
これを実行すると下のような感じになります。
チャットルームを作成すると自分のチャットルームのURLとコピーのボタンが出現します。コピーボタンを押すとクリップボードにコピーされるのでメールやSNS等に貼り付けて相手に送ることが出来ます。
もちろんユーザネームを教えて検索機能で検索してもらうことも出来ます。
これでチャット機能はある程度使えるものになったと思います。最後にfirestoreのセキュリティルールを書いておしまいです。
firestoreのセキュリティルール
ここで私はfirestoreの構造を少し勘違いしていたことに気付きます。
私は、以下のように考えていました。
collection -> document -> field
しかし実際は、
collection -> document -> collection -> document -> ...
といくらでもネストを深く出来るのです。つまり
と考えていたものは、ownerやmemberなどをまたコレクションとして入れることが出来たということです。firestoreのルールもこれらのコレクション・ドキュメントごとにルールを書いていきます。
今回は読み取りは全てのユーザが可能で書き込みはchatsが全てのユーザ、それ以外の書き込みはオーナー、つまりチャットルームの作成者のみにしたいのです。しかしこれらはフィールドであり、firestoreのルールでは設定出来ません。
ネットで調べたら関数を作ることでフィールドに対しても簡単なルールを適用出来そうなのでそれを実行しようと思います。
今回のルールは別の解釈をすればチャットルームの作成者もそれ以外のユーザもchatsフィールド以外の「書き換え」をさせたくないわけです。
ということは飛んできたリクエストに対して、chats以外のフィールドが元のデータと一致している時だけ書き込みを許可すれば言い訳です。ということでルールは以下のようになります。
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /chatrooms/{userId} {
allow read: if request.auth.uid != null;
allow update: if canUpdateUser();
allow create: if request.auth.uid == userId;
allow delete: if request.auth.uid == userId;
}
}
function canUpdateUser() {
return request.resource.data.member == resource.data.member
&& request.resource.data.owner == resource.data.owner
&& request.resource.data.roomname == resource.data.roomname;
}
}
これで一応のルールは出来たかと思います。
完成品
最後に完成品のURLを載せておきます。匿名認証なのでみなさんの個人情報を私に知られることなく始めれるので是非友達と一緒に使ってみてください。また感想や要望などを開発者のチャットルームで書き込むことが出来ます。「開発者」で検索すると出てくるので、いろいろな意見を頂けるとありがたいです。
感想
ここまで長々と書いてきました。Next.jsを使ってみるという目的は達成出来ました。しかし、StaticGenerateやServerSideRenderingなどNext.jsの長所は全然活かせていなかったかなと思います。
しかし、素のreactで書くより全然早いサイトになったのは間違いないと思います。
あとfirebaseの素晴らしさが身にしみてわかりました。firebaseの仕組みは今やっているチーム開発のバックエンドの参考になると思いました。
今度はNext.js × SQLdatabaseを使ってサービスを作ってみたいと思います。
最後に私の今回のプロジェクトのgithubのリポジトリ
とNext.jsを使うきっかけを下さったとらハックさんの動画
を紹介して終わります。
長い間お付き合い頂きありがとうございました。
この記事が気に入ったらサポートをしてみませんか?