React Native x Golang オンラインサロン開発イベント - TheHackチーム開発第3回

# プロジェクト概要

- プロジェクト名：Cilotta（サイロッタ）
- チーム名：第3回_チーム開発_チーム2
- メンバー数： 5名
- [開発リポジトリ](https://github.com/the-hack-community/teamdev-2023-apr-team2)

# イベント詳細 :triangular_flag_on_post:

- イベント名：TheHackチーム開発第3回
- イベント概要：ReactNativeによる地図を使ったアプリ開発
- イベントルール
    - ReactNativeでアプリを実装
    - GoogleMapsを利用する
    - Firebaseで認証を行う（Google, Facebook認証）
    - Firebase DynamicLink を使って リンクを踏むと アプリの特定のページが開くようにする
    - React Navigationを利用して下部のタブナビゲーションを利用する。
    - プッシュ通知を実装する

# プロジェクトのスコープ :triangular_ruler:

- 何を開発したか
    - 目的地付近の駐輪場をナビゲーションするアプリ
- どのような機能が含まれるか
    - トップページ
        - サインイン（Google・Facebook認証）
        - サインアップ（Google・Facebook認証）
    - 地図ページ
        - 目的地の検索
        - 目的地付近の駐輪場を表示する
        - 選択した駐輪場の料金や無料時間を表示する
        - 選択した駐輪場を経由したナビゲーションルートに切り替える
        - お気に入り登録
    - 履歴ページ
        - お気に入り登録したナビゲーション結果を表示する
- 駐輪場API
    - 緯度と経度の範囲から該当する駐輪場の情報を返却する
- ユーザ管理
    - OAuthしたIDとデータベースのIDを紐づける
    - 履歴はデータベースのユーザ情報に紐づける
    - DBはPostgreSQL
- セッション管理
    - CSRFとtoken

# プロジェクトの計画 :bookmark_tabs:

- スケジュール
    - 04/01(土) - 05/25(木)
- 作業の分担
    - バックエンド/フロントエンドに分けて希望を聞きつつアサイン
- プロジェクト管理
    - Github Projectで管理
        - イテレーション単位でタスクを処理

# 開発プロセス :calendar_spiral:

- 使用したツールや技術

| |採用技術|
|-|-|
|バックエンド|Echo|
||Gorm|
|データベース|PostgreSQL|
|フロントエンド|React Native|
||Expo|
||TypeScript|
||Tailwind CSS|
||react-native-maps|
|プロジェクト管理|GitHub Project|
||Figma|
||FigJam|
|ビルド他|Turborepo|
||ESLint, Prettier|
||PNPM|
||Docker|
||czg, husky, lint-staged, validate-branch-name|

# 開発成果 :clapper:
- 概要
    - 音声入力によってキーワードを取得し、キーワードを元に画像生成AIから画像生成を行い投稿する

- 実装した機能
    - ユーザ管理
        - ログイン
        - ログアウト
        - ユーザ作成
    - 画像生成
        - 音声入力
- 実際の動作画面のスクリーンショット
    - ログインページ
      <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245380/ea4a212a-2ba7-b4b3-c72e-f5583f77a197.png" width=300/><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245380/febd9c97-a3f5-9442-9230-1b1d25f12614.png" width=300/>
    - 地図ページ
        <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245380/a0fd3e76-7351-f161-491a-c0ac0ec417e2.png" width=300/><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245380/d5a958ba-5196-8e84-ae03-e064cafcd8a3.png" width=300/>
    - 履歴ページ
      <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245380/1d3fe176-ca8c-9337-cd3e-40446d7f27ff.png" width=300/>
    - プッシュ通知
        - 新たな駐輪場が追加されたら通知される

# 改善点と今後の展望 :bow_and_arrow:

- 実際の運用での課題や問題点
    - 開発関係
        - 起動直後のナビゲーションの挙動が不安定
        - FacebookとGoogleログインでユーザIDがそれぞれ作られてしまう
        - 履歴ページの補足情報が固定値
        - 履歴ページへの遷移アニメーションが不安定
        - 履歴ページのAPI消費が多くなる
        - プレビュービルドが起動しない
        - デザインを詰め切れなかった
    - プロジェクト関係
        - メンバーアサイン
        - スケジュール管理
        - メンバーの離脱が多かった
- 今後の開発の方向性
    - パフォーマンス・チューニングが必要
    - ユーザから駐輪場を更新する仕組み

# チャレンジしたこと :fried_shrimp:
| |内容|感想|
|-|-|-|
|未タッチだった技術を採用|Echo|Golangサーバ|
||Gorm|O/Rマッピング|
||Expo|RNラッパー、多機能ではあるがネイティブ機能を使うライブラリ（Firebaseなど）を使う場合でもワークフローが変更されるため言われているほど簡略化はされない|
||Expo Router|最近ファイルベースルーティングが採用された、メンバーからの要望で採用|
||React Native|基礎部分はReact共有だが、HTMLタグやいくつかのCSSプロパティがないことやReact Native専用のライブラリを要求することが多い、fetchの認証処理もやや特殊になっている|
||react-native-maps|React Nativeの地図ライブラリはこれだが、周辺ライブラリがメンテナンスされづらくなっていっている|
|採用後に外した技術|GRPC|サーバ間通信に採用したかったが、React Nativeで活用できるライブラリがconnectのみで、ドキュメント未整理かつ検証も通らなかったため採用せず|
|デザイン|アプリデザイン|爽やかなイメージで作成|
|プロジェクト管理|GitHub Project|イテレーション単位のタスクアサインにチャレンジ|
|アーキテクチャ|Clean Architecture|参考にしたGolangのリポジトリが採用していたため採用|
||DB|レスポンス速度を意識してデータベース設計を行った|

# 反省点 :beer:
- メンバー離脱が多かった
- 環境構築に考慮漏れが出てしまった
- ロゴデザイン、アプリデザインが作れなかった
- いくつかイベントルールを達成できなかった

# オンラインサロンの魅力 :chocolate_bar:

- サロンで学べることやメリット
    - 具体的な目標を持てるのでしっかりとアウトプットが出来る
- サロンメンバーの活動や交流の様子
    - SlackとGatherで協力しながら開発を行っている
- サロンに参加して得られる成果や成長のポイント
    - プロジェクトでは試せない技術もどんどん取り込んで試せる
    - 他の人の実装を参考にできる

# 第4回のイベントが近日開始なので一緒にチーム開発をしてみよう！ :tada:
## サロン参加方法
- 参加に必要な手続きや料金
    - 1,600 ~ 2,800円/月
    - CAMPFIREから参加可能
- サロンの特典や割引など
    - 2023/05/29現在、割引特典あり
- サロンへの参加方法や連絡先
    - https://community.camp-fire.jp/projects/view/620269