【個人開発】目標管理アプリを作っています


# なぜ作ろうと思ったのか
- 最近、技術検証的なプロダクトを3つ作ってます
  - 作ったもの
    - クリーンアーキテクチャとサーバーサイドTSを使った[サバゲ動画まとめ](https://airsoft-videos.com/)
    - フロントエンドで完結するまったくサーバーを使わない[アイドル判定AI「セレン」](https://celebsearch.deg84.app/)
    - ChatGPTのAPIを使った[名前ジェネレーター](https://name-generator.deg84.app/)
  - これらは技術検証が主で、使ってもらうことはあまり考えられていません
    - もちろん使ってもらえたら良いなーとは思ってはいます
- そろそろちゃんと使ってもらえるアプリ（サービス）を作りたいなぁと思い始めました

今まで色々開発してきていて、自分が使いたいものを作らないとモチベーションが保てないのは分かっていたので、ちょうど欲しいと思ってた目標管理をするアプリを作ることにしました。

# 作っているもの
- 目標管理アプリを作っています
- 名前は今のところAchievva（アチーヴァ）を予定しています
- 中長期的な目標を1つ設定し、日々のアクティビティを登録していくものです
  - 例えば、TOEICで満点取るとか、アプリをリリースするとかです
  - 毎日やることを登録するパターンもあるとは思いますが、Achievvaはそのパターンではないです
    - 要望が多ければそのパターンにも対応するつもりではありますが、まずは今のパターンでリリースする予定です
- 後述しますが、Expoでのアプリ開発とNext.jsを使ったWeb版の開発を同時に始めましたが、今はExpoでのアプリ開発に注力しています
  - Web側はtRPCのAPIサーバーとして利用しています

このプロダクトは、株式会社mofmofの「水曜日の個人開発」にサポートされています。

https://indie-dev.mof-mof.co.jp

# 技術的な話
## 技術スタック
### ベース
- [create-t3-turbo](https://github.com/t3-oss/create-t3-turbo)
  - turborepo
  - T3 Stack
  - Expo
- Storybook
- Jest
- Firebase
- [Neon](https://neon.tech/)

### Web側
- T3 Stack
  - Next.js
  - tRPC
  - Tailwind CSS
  - Typescript
  - Prisma
- Firebase Auth
- Vercel

### アプリ側
- Expo
  - Expo Router
- EAS

## crete-t3-turbo

https://github.com/t3-oss/create-t3-turbo

TurborepoでT3 StackにExpoを追加したテンプレートです。

これをベースに始めてみました。

ただ、FAQにもあるようにNextAuthがExpoに対応していないので、アプリ側の認証周りは自分で書く必要があります。
また、Next.jsとExpoのコードを共通化しようとした場合も、SolitoやTamaguiなどの共通化する仕組みは自分で入れる必要があります。

全体的にはcrete-t3-turboで始めてよかったとは思ってますが、思ってたより自分でやらないといけないことも多いなという印象です。

## Neon
PlanetScaleのPostgreSQL版とも言えるNeonを使ってます。
Vercelが発表したVercel Postgres。あれの裏側で使われているのもNeonです。

PlanetScaleでも良かったんですが、MySQLよりPostgreSQLの方が慣れてるのもあり、今回はNeonを使ってみることにしました。

## EAS Build
今回初めてEAS Buildを使ってみました。
結果、Expo（React Native）でアプリ開発するなら必須級だと思いました。

一番大きいのはManaged Workflowで出来ることが増えたことです。
以前ならBare Workflowじゃないと出来なかったネイティブ周りのことがManaged Workflowのままで触れるのはヤバすぎます。

以前作った通知くんというアプリがありますが、これは課金があったのでejectしてBare Workflowで開発をしていましたが、今ならejectせずにManaged Workflowのままで実現できそうです。

ちなみに、EAS Buildは[月30回（iOSの場合は15回）までは無料](https://expo.dev/pricing)ですが、開発と本番ビルドを行うことを考えるとちょっと少なめなので、開発ビルドはEAS Buildをローカルで実行して、App Configuratorで実機転送して確認しています。
```shell
eas build --platform ios --profile development --local
```

# その他苦労ポイントとか
大小様々ですが色々あります。もし興味あるものがあればコメント頂けたら補足したりしたいと思います。

- ExpoとNext.jsのUIを共通化しようとしてTamaguiを使ってみたが止めた話
- Storybookがviteベースになって、知見が使えなかった話
- NextAuth.jsからのFirebase Authに乗り換えた話
- 気付いたらNeonの無料枠を食い潰してた話
- 個人開発を始めると体調が悪くなる話

## NextAuth.jsからのFirebase Authに乗り換えた
みんなに聞いてみたらところこの話が一番聞きたいってことだったので、NextAuth.jsからのFirebase Authに乗り換えた話を。

ベースにしているT3 Stackでは、認証周りにNextAuth.jsを使っています。

Expoは対応していないので、Expoの認証周りにNextAuth.jsは使えません。
これは、前述の通りcreate-t3-turboのFAQにも書いてあります。

Expoで認証を行う場合の選択肢は、Clark、Supabase Auth、Firebase Auth、Auth0などがありますが、今回はFirebase Authを選択しました。

Crashlyticsなど他のFirebase製品を使うのが決まっていたのと、Firebase Authは今まで何回も使ってたりしたのが理由です。

Clarkは公式でcreate-t3-turboベースのサンプルプロジェクトを公開しているので、こだわりがなければClarkを使うのが恐らく一番手間なく使えるんじゃないかなと思います。使ったこと無いので詳細は不明ですが。

https://github.com/clerkinc/t3-turbo-and-clerk

そして、ExpoをFirebase Authにしたこともあり、NextAuth.jsを使う必要ないなと思ったのでWeb側についてもNextAuth.jsを使わずにFirebase Authを直接使ってます。

ちなみに、Expo側ではReact Native Firebaseを使っているのに対し、Web側はFirebase JS SDKを使っています。

### アプリ側からWeb側のAPIを叩く辺りの流れ
参考程度にこんなことしてるよっていうのを書いておきます。

1. （アプリ）Firebase Authで認証、`idToken`を受け取る
`auth.currentUser.getIdToken()`
2. （アプリ）Web側のAPIを叩くときにヘッダーに受け取ったidTokenを付与する
`Authorization: Bearer ${idToken} `
3. （API）送られてきたidTokenを受け取り、Firebase Authに確認する
`auth.verifyIdToken(idToken)`

これでAPIを叩いてきた人がFirebase Authに登録されている人であることが確認できます。
あとはUserも特定出来るのでその情報から必要なデータを引っ張ってくればOKって感じです。

NextAuth.jsがあると1レイヤー増えるので、Firebase Authでに対応していないOAuthプロバイダーを使いたいとかがなければFirebase Authを直接使うので良いかなと思います。

# まとめ
ということで、まだまだ開発中で、個人開発あるあるの時間がかかりすぎるとモチベーションが下がってリリースされずに終わってしまう可能性が出てきてしまっていますが、引き続き開発をしてリリースできるように無理なく頑張っていきたいと思います。

色々書きましたが「React Nativeでアプリ開発をするならEAS Buildを使う」これだけ覚えておいて頂ければ幸いです。以上です。