大学生Railsエンジニアが、1人でWebとアプリをリリースするまでの3ヶ月間の話


Qiita初投稿なのでお手柔らかに。

自分は大学生ながら都内のスタートアップでエンジニアをしています。

普段はRailsでのWebサービス開発がメインで、SwiftもKotlinも触ったことすらありませんでした。

経験ゼロのReact NativeとExpoでリリースまでに得た知見を残していきます。

開発したサービス


SportsLab | スポーツをより深く楽しめる新しいメディア

コメントと共にスポーツのニュースを読めるサービスです。

Webとアプリの両方を1人で開発・運用しています。スタートアップあるあるですね笑。

使用技術

ざっくり使用している技術を紹介します。

Web: Rails 5.0, jQuery

アプリ: React Native, Expo, (TypeScript)

インフラ: ElasticBeanstalk(AWS)

認証: Firebase Auth

CI: Circle CI

スタートアップではよくある感じの技術構成だと思います。

Railsのエコシステムや周辺ライブラリの豊富さには助けられました。

アプリについては僕がSwiftやKotlinをかけないため泣く泣くReact Nativeを採用しました。

開発スケジュールを振り返る

開発の時間軸としては

12/24
記念すべきfirst commit
1/1
年明けにEC2にデプロイ
1/2
ドメインを取得してWeb版をローンチ
1/4
アプリを開発開始
2/1
Appleに初めて申請
2/13
朝起きたらアプリが公開されてました!
2/20
安定版がストアで公開される

一人で開発して良かった事

今までのJSの経験を生かす事が出来た

React Native & Expoを採用した事でSwift, Kotlinを勉強する事なく純粋にJavaScript(TypeScript)を書くだけでモバイルアプリを開発できた、というのが一番ですね。

OTAアップデートで簡単に更新できる

また、ExpoにはOTAアップデート機能があるのでそちらを使えばストアに申請する事なくユーザのアプリを強制的にアップデートできるのも魅力の1つです。

デザインについても Native BaseReact Native Elements といったUIライブラリが揃っているのでCSSをほとんど書く事なく開発を進められたのも大きかったです。

一人で開発して辛かった事

気軽にストア申請できない

ユーザによって使うアプリのバージョンがまちまちになってしまうので、API側でルーティングの変更などの仕様を変えられないのが辛いです。

TypeScript難しい😢

React Nativeは完全に独学で、今も付け焼き刃の状態でコードを書いているのでアプリの挙動が不安定なのがネックでした。

少しでもバグを減らすためにTypeScriptを導入しましたが、動的型付けであるRubyしか書いてこなかったので、そもそも型ってなんですか?というレベルで、TypeScriptの恩恵を十分に受けられてないです。

これから勉強していきます!

ファイルの肥大化

useEffectで通信処理をViewにベタガキしてるのでファイルが巨大化してカオスofカオス。

Reduxや, Redux-sageなどのミドルウェアの学習と導入が待たれる。。。(そう言えば、つい最近FaceBookが新しい状態管理ライブラリを出してきましたね!)

申請が通らない!!!

最初App Storeの申請で数週間悩まされました。理由はこいつでした。

4.2 minimum functionality We found that the usefulness of your app is limited by the minimal features it includes.

どうも調べたところお前の作ったアプリは⚪️ミだからアウト!っていう意味らしいです。

Push通知実装したり、記事の検索機能つけたりいろいろしたのですがダメでした。

ではどうやって通したかというと・・・

ウォークスルーを実装しました!!!

それだけです。

正直なんで通ったのか分からないです。

どうやらアプリでないと得られないUXを訴求したのが良かったっぽいです。

同じ理由でリジェクトされてる人が一人でも多く救われますように。

ExpoをアップグレードしたらFacebookでログインできなくなった

ふと朝起きると同僚からSlackで同僚からメンションが来ていました。

Facebookでログインしようとするとアプリがクラッシュするんだけど

報告を受けた瞬間、顔面蒼白になりました。

急いで調査を開始するも、全く原因を特定できませんでした。

焦りを加速させたのはSentry経由でSlackにエラー通知も流れてこないという事でした。

つまり具体的にどこのコードでクラッシュしてるのか検討がつかない。

公式ドキュメント通りに実装してるし、どこが悪いのか悩む日々。

分からなさすぎてExpoにIssueまで立てちゃう始末。

Problem login with Facebook and Firebase

そのあともう一度Expo37のchangelogを調べていくと・・・ありました!!!

読んでいくと、途中にこんな記述が。

- In the Expo Client, all of your Facebook API calls will be made with Expo's Facebook App ID. This means you will not see any related ad info in your Facebook developer page while running your project in the Expo Client.
- To use your app's own Facebook App ID (and thus see any related ad info in your Facebook developer page), you'll need to [build a standalone app](../../distribution/building-standalone-apps/).

どうやら開発環境ではFacebookログインはできなくなったようです。

なのでビルドして動作確認する必要があるようでした。

ちなみに僕はこれに気付かず

Possible Unhandled Promise Rejection (id: 0):
[Error: Unsuccessful debug_token response from Facebook: {"error":{"message":"(#100) The App_id in the input_token did not match the Viewing App","type":"OAuthException","code":100,"fbtrace_id":"********"}}]

というエラーを3日間眺める羽目になりました。。。

1人でRailsでAPIを作った感想

JSONの整形にはActive Model Serializerが神

デフォルトでインストールされてるjbuilderは評判悪そうなのでActive Model Serializerを採用しました。

スター数も多いし大丈夫そうって思ってた矢先、更新が止まるという。。。

しばらくはこれで行く予定です。

Netflixが出してるfast_jsonapiっていうのが来てるらしいのですが学習コストが高そうなので断念しました。

Active Moel SerializerはActive Recordベースでかけるため直感的ですがSerializer側に値を渡す時のやり方が分からなくて最初苦労しました。

検索してもヒットするのが古いバージョンの記事ばかりで諦めかけていた、そのとき!

ActiveModelSerializers(0.10系)のインスタンス生成時に引数を渡してSerializerクラス内で使う方法

こちらの記事を発見しました。これに全て書いてあります。神!!!

重い腰を上げてFat Controllerを解決

あと初心者Railsエンジニアあるあるですね。

これどうしようかつい最近まで悩んでいたのですが

実務で学んだRailsの設計・リファクタリング

こちらを参考にさせて頂きました。

POROでサービスクラス(上記の記事ではWorkflows)を作ってそこに切り出そうというアプローチです。

あとControllerを分けてCRUDしかメソッドが作成されないようにする。

試してみましたがいい感じです。自分の書き方が合ってるか自信ありませんが。。。

突然のDockerの導入

実はWeb版のCSSは弊社のCEOが自ら書いています。

で、そのCEOのPCで環境構築しようとしたらなぜか環境構築で詰まりまして。。。

試行錯誤した結果、初めてDockerなるものを導入しました。

と言っても、開発環境でDockerfile書いただけです。

本番環境でのECSやFargateを使ったDockerの運用はリリース後のお楽しみという事で・・・。

Docker for Mac予想以上に重かった!

PCは高いやつを買おうと心に決めました。

こんな感じです!

追記(8/30)

リンクが切れていた記事があったためリンクを修正