React / Firebaseでブックマーク管理アプリを作ってみた【個人開発】

# どんなアプリか
[Bookmark-Board](https://bookmark-board.com/)というシンプルなブックマーク管理アプリを開発しました🎉
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200228/475cd1fc-8b55-4f24-0537-88371acc7f78.png)

このアプリはブックマークの整理・共有といった要素にフォーカスしています。
一言メモやカラー設定によってより情報を見えやすくし、共同編集や公開機能によって、自分が使ったブックマークリストを他の人にも使ってもらえるような、情報共有ツールとしてのブックマークアプリを目指しました。
# 特徴
・ブックマークに対してカラーの設定が可能（視覚的に分類しやすくするため）
・ブックマークに対して自分なりのメモが保存可能（ひとことメモ的な）
・複数人で一つのブックマークグループの共同編集が可能
・ログインしていないユーザに対してもブックマークリストの公開が可能
カラー設定やメモ機能を使うことで、次のように見栄えを整えて公開することができます
👉 [サンプル公開ページ](https://bookmark-board.com/public-bookmarks/AYHzFeinyTnB2kxEXnps)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200228/e97aae43-ef8f-26ca-9c26-562531ddca4e.png" width="500">

# 開発経緯
特定ジャンルのブックマークを数人でシェアしながら貯めていけるようなサービスが使いたかったので開発しました。既存では[Raindrop.io](https://raindrop.io/)なんかが有名かと思います(こちらは開発の際、非常に参考にさせて頂きました)
またスキル的な側面で、Next.jsを使ったサービスを開発したかったという思いもありました

# 使用技術

## システム構成
フロントエンドはVercel-Next.js、バックエンドはFirebaseという構成になっています。
![スクリーンショット 2021-04-09 1.15.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200228/08762d9f-a59a-4884-8302-e2a7892891c6.png)



## 使用している主要なライブラリ

- React
- Firebase
    - Authentication : ログイン
    - Firestore : ブックマーク全般のデータ保存
    - Cloud Functions : ブックマークのOGPの取得
    - Storage : プロファイル等の画像保存
- Next
- React-redux：状態管理

reduxでは[redux-toolkit](https://redux-toolkit.js.org/)にお世話になっています。覚える敷居は高いものの、慣れてくるととなかなか離れられないツールですね。[Recoil](https://recoiljs.org/)も良さそうだったので今後使ってみたいと思っています

# 工夫点など
## データ取得方法
Next.JSは[SSG](https://nextjs.org/docs/basic-features/pages#static-generation-with-data)を使うことでビルド時にデータを取得しページに埋め込むことができるので、描画が非常に高速になるという利点があります。この利点を生かしたかった一方で、Firebaseのスナップショットリスナーでリアルタイムにデータ更新したいという思いもあったため、次のようにページごとにデータの取得方法を分けています。

- 公開ページ・・・SSGでデータを埋め込む。Firebase Clientは使用しない
- 編集ページ・・・SSGではデータ以外の描画を行う。ブックマークリストはFirebase Clientを用いて[スナップショットリスナー](https://firebase.google.com/docs/firestore/query-data/listen?hl=ja)で取得したうえ、描画する

また、OGP画像の取得もそこそこ時間がかかってしまう為、[ImageKit.io](https://imagekit.io/)を利用し表示に必要な画像のトリムとキャッシュ化を行い、表示のパフォーマンスを向上させました。
(計測結果は[サンプルページ](https://bookmark-board.com/public-bookmarks/AYHzFeinyTnB2kxEXnps)のもの）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200228/8a80530d-c285-3aa4-c9e4-d61e6edbc291.png)

今回のアプリではほとんど使い切れていませんが、`ImageKit.io`には非常に豊富な[Image Transformations](https://docs.imagekit.io/features/image-transformations)が用意されているため、画像を扱うケースにおいては色々と活躍しそうな気がします

## 操作感
Bookmark-Boardでは、ブックマークの並び替えをドラッグ&ドロップで行えます。また、並び替えだけでは無く、ブックマークを別のグループに移動したい場合も、グループにブックマークをドロップする事で直感的な移動が可能となります。
![Dnd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200228/ab55ca97-c81c-4071-0084-fff35f04d48e.gif)


ドラッグ&ドロップは[React Dnd](https://react-dnd.github.io/react-dnd/about)というライブラリを用いて実現しています。他にも[react-smooth-dnd](https://github.com/kutlugsahin/smooth-dnd/)など、シンプルですぐに使えそうなものもありましたが、[スマホの対応（Touch Backend）](https://react-dnd.github.io/react-dnd/docs/backends/touch)やドロップ先を自在に決められる点など拡張のしやすさから、こちらを選定しました。
（React Dndは何度か使っていますが、毎回使い方を忘れてしまいます・・・😓）

# 今後の予定
## Chrome拡張
現状、ブックマークの登録にいちいちページに移動してURLを貼り付けないといけませんが、RaindropのようにChrome拡張でブックマークをそのまま登録できるようにしたいとは思っています。
**2021/05/28 追記**
Chrome拡張に対応しました 🎉

https://chrome.google.com/webstore/detail/bookmark-board/bgnimjpmdfcgchcddbmmadpgadjapicf?hl=ja

Chrome拡張は初だった事ももあり、設定や認証まわりに結構躓いたので、忘備録としてReact+Firebase+Chrome拡張の構成における開発手順をZennにてまとめてみました。よければこちらも覗いてみてください。

https://zenn.dev/mktu/articles/9f17fe89e74282


## その他改善
一括削除や一括移動などのUI機能追加、また通知やSNS連携についても現状ほとんどノータッチなので、必要に応じて順次拡充していこうと思います。

# 最後に
読んでいただきありがとうございます。
まだまだ改善の余地も多いですが、時間あるときに覗いていただけると幸いです！