サクッとexampleコードを書くつもりが、nativeコードにハマりにハマって1ヶ月かかってしまいました。。。
js界隈の人間には、react-nativeのnative側のコードをいじるのが、とにかく辛かった。
今回作ったexample
概要
- タイトルの通り、GCP、Firebase、GraphQL、react、react-native、appetize.ioを使い、web、iOS、Android向けにFirebaseのauthログイン + リスト表示ができるexampleを作成
(※使用技術については下記記載)
github
DEMO
web
iOS (appetize.io)
Android (appetize.io)
構成 (使用技術)
backend
実装環境: Cloud Functions for Firebase
- Googleが提供するFunction実行サービス(AWSのlambdaみたいなものです)
- 今回はFirebase連携を使用するため、Cloud Functions for Firebaseで実装
- (余談ですが)
- AppEngineがnode.jsのスタンダード環境の提供を始めたら、そちらを使用するほうが筋が良いか気がするので乗り換える予定
データベース: Google Cloud Datastore
- Cloud DatastoreはGoogleが提供するNoSQLデータベース
- 個人利用で無料利用枠を超えることがほぼないので、気軽に使用できる
- 「OR」や「IN」や「!=」等のクエリが使用できないので、サービス開発に使用する際は注意
言語: Node.js
- backendの言語は、選択肢が幾らでもあるので基本開発メンバーの好みで良いと思いますが、今回は以下の理由からNode.jsを採用しました
- 将来的にSSR(サーバーサイドレンダリング)を実装することになった場合に、現状Node.js以外の選択肢が無いため
- Node.jsはGraphQLの公式がサポートしているため
API実装方式: GraphQL
- REST APIに比べ、GraphQLでは厳密に仕様が定義でき使いやすい
- graphiqlという、API開発ツール(RESTのpostmanみたいなもの)の出来が良い
- 実装に迷った際は、GitHub API v4のドキュメントを見れば、正解が書いてあるので要確認
認証: Firebase
- 今回はFirebaseのサービスは認証以外は使用していませんが、web、native共に便利サービスが充実しているので、今後の拡張を想定し組み込みました
- (余談ですが)
- 単に認証を行いたいというだけであれば、Auth0の方が高性能です
frontend(web)
実装: React
- Facebookが開発しているViewライブラリ
- React v16.3.0で追加されたOfficial Context APIにより、React単体で扱えるアプリケーションの幅が広まった
GraphQLクライアント: react-apollo
- GraphQLのクライアントライブラリ
- 現状、GraphQLクライアントはapolloと**relay**の2択で、かつGraphQLの公式はrelay側なので悩ましいところですが、relayはrelay-compiler等の強い縛りがあり柔軟性に欠けると感じ、今回はapolloを採用
認証: Firebase
- 公式のドキュメントが充実しているので、楽に実装可能
- 今回は、公式で認証のReactコンポーネント(react-firebaseui)を提供しているので、そちらを採用
実装環境: Google App Engine
- 自作のwebアプリを簡単公開できるPaaS(yamlに設定書いてデプロイコマンドを実行するだけでOK)
- 今回は、jsとhtmlの置き場のためだけに使用
frontend( iOS & Android )
実装: React Native
- ReactでiOS、Androidアプリが書けるライブラリ(コードはjavascript)
- 構文的にはReactと一緒なので、React経験者なら簡単に始められる
- が、簡単に始められるというだけで、リリースまでの実装にはnativeコード側のObjective-Cやjavaやgradleを修正可能性が高いので、覚悟を決めてから、始めた方が良いです
- それでも今からSwift & Kotlinを1から勉強するよりはコスパ良いと思います
GraphQLクライアント: react-apollo
- webと同様にapolloを採用
- nativeとwebは全く同じコードで実装できる
認証: react-native-firebase
- react-nativeのfirebaseSDK
- Firebase公式では無いが、サービス自体は一通りサポートしている
- 導入にはnativeコードを修正する必要があります
- また今回はGoogleアカウントログインも実装しており、それにはreact-native-google-sign-inを導入し、連携されせる必要があります
- react-native-firebaseとreact-native-google-sign-inの連携方法
- さらにreact-native-google-sign-inを導入するのにもnativeコードを修正する必要があります
データストレージ: AsyncStorage
- react-nativeの標準で含まれている簡易データストレージ
- 今回は、Auth Tokenの保持にのみに使いたかったので、簡単に使用できるAsyncStorageを採用
ルーティング: react-native-navigation
- ルーティングライブラリ
- 他のルーティングライブラリと比較しリッチなアニメーションが搭載されている
- 今回は、アプリらしい見た目を考慮しreact-native-navigationを採用
- 導入にはnativeコードを修正する必要があります
UIライブラリ: react-native-elements & react-native-elements
- 基礎となるUIライブラリは一つに絞りたいと所ですが、どちらも少しづつ足りないコンポーネントがある感じなので、今回は併用で採用
- ちなみにNativeBaseという強力なUIライブラリがあるが、他のコンポーネント群との併用が困難だと感じたため、今回は不採用
iOSのbetaアプリ配信: [fastlane] (https://github.com/fastlane/fastlane) & TestFlight
- fastlaneはiOSのリリースを自動化できるツール
- TestFlightはiOSアプリのテスター向け配信をサポートしてくれるサービス
- 現状は、以下のコマンドで「fastlaneでbetaアプリを更新し、TestFlightからテスターに配信」できるようにしている
cd native
npm run ios:bate
- Fabricも実装していますが、今回はより簡単なTestFlightでの配信を採用
Androidのbetaアプリ配信: 手動apkファイルをダウンロードで運用
- こちらもFabric等のツール自動化できそうですが、apkファイルを出力して実機Androidでダウンロードすれば事足りるかなと思い手動で運用
- お手軽実装でよければ、apkファイルをビルド後にgoogle cloud storageにアップロードして、それをダウンロードできるWebサイトをApp Engineで立てるくらいで良いかなーと思っている
iOS & AndroidのDEMO実行: appetize.io
- アプリをアップロードすると(謎技術により)、Webブラウザでネイティブアプリを動かすことのできるサービス
- 無料利用でのアクセス制限は存在するが、個人開発レベルなら無料で使用できる
- 動作も、かなりサクサクで動くので気軽にDEMOを見せたい時に使える
- また、fastlaneを使用することで自動アップロードも可能
一通りの開発を終えての総評
-
Google Cloud Platformは超簡単にアプリケーションを作って公開できる
- AppEngineやDatastoreのお手軽感は、AWSでは体験できなかった間隔で素晴らしい
- 個人開発なら、ほぼ無料で使えるのも
-
GraphQLはREST APIの曖昧な部分をカバーできる仕様になっており、API仕様として優れている
- 以下の点でAPI仕様として優れている
- REST APIではrequestパラメータやresponseパラメータに厳密に型やプロパティを保証することができない
- GraphQLではrequest、response共に厳密に定義する設計になっているため解決
- REST APIにもswagger等のドキュメント生成ツールが存在するが、そのドキュメントと実装が乖離していないことを保証することができない
- GraphQLでは、graphiql等のツールにより実装に沿ったドキュメントを確認することができるので解決
- 以下の点でAPI仕様として優れている
-
react-nativeは不満を感じることも多いいが、魅力的に感じることも多いい
- 不満
- native codeを触れる必要が出た時にひたすらハマる(今回の開発期間の1/2はnative code関連の修正対応)
- StyleSheetがwebに比べるとショボい
- スタンダートなコンポーネントが全て揃っているUIライブラリが無い
- iOSで動いてAndoridで動かない、Andoridで動いてiOSで動かないが事がナチュラルに発生する
- (当たり前だけど)betaビルドやリリースでは、やはりネイティブの知識が必要
- 魅力
- Reactの構文が分かれば、AndroidとiOSアプリを作成する事ができる
- jsコードに関しては、AndroidとiOSは(ほぼ)ワンコードで実装できる
- swiftやKotlinと比べて、開発スピードが早い(はず)
- 一般的なGUIに必要なコンポーネントは一通り揃っている(はず)
- 不満