React Nativeで作ったアプリをリリースしてから1年経ったので振り返ってみる


![Frame 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170824/fcdbe13f-04d9-e44c-a53a-a7a7d2753a77.png)

[React Native製、予定作成アプリ「ペペロミア」を公開しました](https://qiita.com/wheatandcat/items/3324dfd141729e46009f)

以前記事にしたペペロミアが公開してから1年経ったので振り返りも兼ねて記事にまとめてみました。
個人プロダクトのアーキテクトとかの参考になれば良いかなと思います。


# 主に使用している技術

 * アプリ
    * [Expo(React Native)](https://expo.io/)
 * Backend
    * [Golang](https://golang.org/)
 * Web版
    * [Nuxt.js](https://ja.nuxtjs.org/) 
 * ヘルプサイト
    * [Gatsby.js](https://www.gatsbyjs.org/) 
 * LPページ
    * [React](https://ja.reactjs.org/) 
 * その他の使用技術 /ツール
    * [TypeScript](https://www.typescriptlang.org/)
    * [Firebase](https://firebase.google.com/)
    * [Figma](https://www.figma.com/)
    * [GraphQL](https://graphql.org/)
    * [GitHub Actions](https://github.co.jp/features/actions)
    * [MDX](https://mdxjs.com/)
    * [SwaggerHub](https://swagger.io/tools/swaggerhub/)

# GitHub

前はモノレポで1つのRepositoryで全Sサービス管理していたが、各サービスごとにわけるようにしたので以下の通りです。

 * [Peperomia](https://github.com/wheatandcat/Peperomia)
 * [PeperomiaBackend](https://github.com/wheatandcat/PeperomiaBackend)
 * [PeperomiaWeb](https://github.com/wheatandcat/PeperomiaWeb)
 * [PeperomiaHelp](https://github.com/wheatandcat/PeperomiaHelp)
 * [PeperomiaLandingPage](https://github.com/wheatandcat/PeperomiaLandingPage)


# リリースノート

今までの主な更新リリース内容は、こちらで確認できます。

https://peperomia.app/information

# ペペロミアとは

プロジェクトの概要は、こちらを参照

https://peperomia.app/about

# アプリ

https://github.com/wheatandcat/Peperomia

<img width="350" alt="スクリーンショット 2020-07-27 23.09.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170824/eee8e23f-749c-7b9d-f63a-5833a7f2edc3.png">

■ Apple Store
https://itunes.apple.com/us/app/%E3%83%9A%E3%83%9A%E3%83%AD%E3%83%9F%E3%82%A2/id1460583871?l=ja#?platform=iphone

■ Google Play
https://play.google.com/store/apps/details?id=com.wheatandcat.peperomia

## 概要

スケジュール管理アプリ。
アカウント登録すると、Push通知、Web版、シェア機能など利用できるようになります。


## 使用技術 / ツール

### デザイン設計

Figamaを使用しています。
https://www.figma.com/

Figmaについては以下で公開しています。
[ペペロミア Figma](https://www.figma.com/file/YYon1ahSQ7W15Mug0LsovHws/%E3%83%9A%E3%83%9A%E3%83%AD%E3%83%9F%E3%82%A2?node-id=0%3A1)

Figmaに関しては前に記事にしているので以下を参照
[エンジニアでも出来る！Figmaを使って自作アプリをリニューアル](https://qiita.com/wheatandcat/items/a1a8122b3a7edadfe477)

### アプリ作成

アプリは**Expo**を使用しています。
https://expo.io/

### データベース

アカウント認証前は、[SQLite](https://docs.expo.io/versions/latest/sdk/sqlite/)を使用、
アカウント認証後はWeb版でもデータ同期ができるように[Firestore](https://firebase.google.com/docs/firestore?hl=ja)を使用する実装になっています。

### 認証

認証は[Firebase Authentication](https://firebase.google.com/docs/auth?hl=ja)を使用しています。
**Googleログイン**と**Sign in with Apple**で登録できるようになっています。


## 主なリリース内容

### Expo SDKのバージョンアップ

リリース当初がExpo SDK v32でしたが、現在は**Expo SDK v38**で実装しています。

各SDKのバージョンアップのPull Requestがこちら

 - [Expo SDK v33にバージョンアップ](https://github.com/wheatandcat/Peperomia/pull/27)
 - [Expo SDK v34にバージョンアップ](https://github.com/wheatandcat/Peperomia/pull/53)
 - [Expo SDK v35 バージョンアップ](https://github.com/wheatandcat/Peperomia/pull/111)
 - [Expo SDK v36 バージョンアップ](https://github.com/wheatandcat/Peperomia/pull/275)
 - [Expo SDK v37 バージョンアップ](https://github.com/wheatandcat/Peperomia/pull/559)
 - [Expo SDK v38 バージョンアップ](https://github.com/wheatandcat/Peperomia/pull/654)


主なバージョンアップ変更は以下の通り

 * React Native v0.61以降になり**Fast refresh**が導入されたので開発時に高速でリフレッシュできる
 * 元々expo内部に入っていたモジュールが別モジュールに分割
 * webサポートされた（けど、他ライブラリの影響でペペロミアでは、ビルドでコケるので使えていない :sweat: ）


### ダークモードの実装

以下で解説しているのが細かい実装は省略しますが、
[React Native製の公開しているアプリにダークモードを実装してみた](https://qiita.com/wheatandcat/items/05b6f616a59c26f0983d)

現状は、端末の設定を見て通常モード、ダークモードの切り替えを行う実装になっています。
ホーム画面の比較をすると、こんな感じです。
![darkmode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170824/0d804750-cbeb-6e74-8813-db9c9a30bdbf.png)


### カレンダー機能の実装
![calendar001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170824/6e958952-8641-258c-f8b3-83bdd508ac6c.png)

 * スケジュールに日付入力をできるようにしてカレンダーUIで表示するように変更
 * 実装は[react-native-calendars](https://github.com/wix/react-native-calendars)を使用

### Sign in with Appleの実装


<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/w/wheatandcat/20200426/20200426114958.gif" width="180">


 - Sign in with Appleを実装
 - Apple storeの規約でサードパーティのログインを形式の場合はSign in with Appleの実装は必須になったのでFirebase Authenticationに追加
 - ExpoでのSign in with Appleは以下の通りに実
    - https://docs.expo.io/versions/latest/sdk/apple-authentication


### Expo Push通知の実装

<div>
<img src="https://user-images.githubusercontent.com/19209314/85921040-ed699d80-b8b3-11ea-88eb-9b6d8822df23.gif" width="180">
<img src="https://user-images.githubusercontent.com/19209314/85921055-0d995c80-b8b4-11ea-9b22-463a91e5022d.gif" width="180">
</div>

 - Push通知を開いた時に指定の画面を開く機能を実装
 - ExpoでのPush通知は以下の通りに実装
    - https://docs.expo.io/versions/latest/sdk/notifications/

# Backend

https://github.com/wheatandcat/PeperomiaBackend

## 概要

言語は[Go言語](https://golang.org/)で実装
主にアカウント認証後のデータのやり取りのAPIを実装しています。

## 使用技術 / ツール

### フレームワーク

**Gin**を利用して実装
https://github.com/gin-gonic/gin

GraphQLは**gqlgen**で実装
https://github.com/99designs/gqlgen

### デプロイ先

GCPの[GAE](https://cloud.google.com/appengine/docs?hl=ja)にデプロイしています。


### API設計書

RESTful APIのドキュメントは[SwaggerHub](https://swagger.io/tools/swaggerhub/)で実装しています。

以下で、ドキュメントを公開しています。
https://app.swaggerhub.com/apis-docs/wheatandcat/peperomia/1.0.0


## 主なリリース内容

### gomockでのHTTP Requestのテストの実装

Goでテストを書く際にFirestoreにアクセスさせたくなかったのでgomockでメソッドをモック化してテストコードを作成しました。
https://github.com/golang/mock

実装の詳しい内容は以下の記事参照
[GoMockを使ってHTTP Requestのテストを書いてみる](https://www.wheatandcat.me/entry/2020/01/05/094543)

### ExpoでPush通知を実装

ExpoのPush通知のSDKがあるので、こちらを使用して実装
https://github.com/oliveroneill/exponent-server-sdk-golang

カレンダーに合わせてPush通知を送るようにしており、GAEの[cron.yamlのジョブのスケジューリング](https://cloud.google.com/appengine/docs/flexible/go/scheduling-jobs-with-cron-yaml?hl=ja)で定期実行しています。


実装の詳しい内容は以下の記事参照
[ExpoでPush通知を実装してみた](https://www.wheatandcat.me/entry/2020/07/01/192110)

### gqlgenの実装

[gqlgen](https://github.com/99designs/gqlgen)を実装


gqlgenのベースになっているGraphQL Schemaファイルを[graphql-codegen](https://graphql-code-generator.com/)に渡すことでTypeScriptのtypeファイルを自動生成するようにしています。

実装の詳しい内容は以下の記事参照
[gqlgenとgraphql-codegenでGraphQLのtypeを自動生成してフロントエンドのコード作成する](https://www.wheatandcat.me/entry/2020/07/13/231954)

# Web版

https://github.com/wheatandcat/PeperomiaWeb
![web001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170824/c69649b8-05db-5dff-5962-001cb86ddb32.png)

■ URL
https://app.peperomia.info/login
※アプリでアカウント作成していないと利用できません

## 概要

[Nuxt.js](https://ja.nuxtjs.org/) で実装しています。

## 使用技術 / ツール

### UIライブラリ

**Vuetify**で実装
https://vuetifyjs.com/ja

### デプロイ先

こちらもGCPの[GAE](https://cloud.google.com/appengine/docs?hl=ja)にデプロイしています。

## 主なリリース内容

### Firebase Authenticationでサードパーティクッキーの対応

Safariでサードパーティクッキーをデフォルトでブロックされるようになったので、Firebase Authenticationを素で組み込むとエラーになるようになっていたので、そちらの対応

実装の詳しい内容は以下の記事参照
[Firebase Authenticationの「This browser is not supported or 3rd party cookies and data may be disabled. 」の解決方法](https://www.wheatandcat.me/entry/2020/03/21/200404)


### Composition API + TypeScriptの導入

Vue 3.0で導入される[Composition API](https://composition-api.vuejs.org/)を導入
合わせてComposition APIと相性の良いTypeScriptも導入しました。

導入前に以下の3パターンの実装方式を検証

 * パターン①. Composition API + TSXファイル + CSS Modules
 * パターン②. Composition API + Vueファイル + \<script lang="tsx">
 * パターン③. Composition API + Vueファイル + \<script lang="ts">

検証の結果、1番シンプルな**パターン③**で実装しました。

実装 + 検証の詳しい内容は以下の記事参照
[NuxtでComposition API とTSとTSX + CSS Modulesの組み合わせについて考えてみる](https://www.wheatandcat.me/entry/2020/03/29/231814)

### @nuxt/http導入 + スケジュール修正機能の実装

<img src=https://user-images.githubusercontent.com/19209314/81584107-44dba900-93ed-11ea-9e71-efc55456256e.gif  width=480>

ペペロミアのWeb版でのAPIアクセスは@nuxt/httpで実装
https://github.com/nuxt/http

Web側でスケジュール内容の編集の際は@nuxt/httpでAPIにアクセスしてデータ変更を行っている


# ヘルプサイト

https://github.com/wheatandcat/PeperomiaHelp
<img width="480" alt="スクリーンショット 2020-07-28 22.58.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170824/b6ddfa06-05d1-7b9f-3ee6-780589d9c6d5.png">

■ URL
https://amazing-hawking-a280c3.netlify.app/

## 概要

[GatsbyJS](https://www.gatsbyjs.org/)で実装
GatsbyJSは[MDX](https://mdxjs.com/)をサポートしているのヘルプ記事の中身はMDXで記載しています。

## 使用技術 / ツール

### デプロイ先

[Netlify](https://www.netlify.com/)にデプロイしています。

GatsbyJSでのNetlifyデプロイ方法は以下を参照
https://www.gatsbyjs.org/docs/deploying-to-netlify/

## 主なリリース内容

### GatsbyJS + MDXでヘルプサイトを作成

なるべく手をかからず、zendeskやIntercomみたいにお金のかからない方式でヘルプサイトを作りたかったので作成。

実装の詳しい内容は以下の記事参照
[Gatsby.js + mdxでヘルプサイトを作ってみる](https://www.wheatandcat.me/entry/2020/02/15/193720)

ちなみに今だと**Gatsby Cloud**でMDXも使えるみたいなので、こちらの選択式もありかなと思います
https://www.gatsbyjs.com/

# LPページ

https://github.com/wheatandcat/PeperomiaLandingPage
<img width="480" alt="スクリーンショット 2020-07-28 23.25.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170824/9757583c-8c68-bad7-d3af-423d018fa412.png">

■ URL
https://peperomia.app/

## 概要

[React](https://ja.reactjs.org/)で実装しています

## 使用技術 / ツール

### デプロイ先

[Netlify](https://www.netlify.com/)にデプロイしています。

## 主なリリース内容

### LPサイトにアニメーションを追加

![Jul-22-2020 01-20-20](https://user-images.githubusercontent.com/19209314/88080251-cbfd8800-cbb9-11ea-9c71-12995a04fe72.gif)

[react-inview-monitor](https://github.com/snipsco/react-inview-monitor)を使ってスクロールに入ったタイミングアニメーションするように修正

実装の詳しい内容は以下の記事参照
[Reactで作成したLPサイトにアニメーションを追加してみた](https://www.wheatandcat.me/entry/2020/07/22/105942)

### RSS経由からリリースノートを表示

<img width="400" alt="スクリーンショット 2020-07-22 19 12 00" src="https://user-images.githubusercontent.com/19209314/88165619-efbfdd00-cc50-11ea-97e0-db294ea5c413.png">

リリースノートを自動生成するスクリプトを作成してブログに投稿
タグを付けてRSS経由で取得して、LPページに表示させています。

リリースノートの自動生成については以下の記事参照
[リリースノートを自動生成するスクリプトを書いてみた](https://www.wheatandcat.me/entry/2020/06/14/220724)


# 今年〜来年への開発予定

## Firestoreの設計見直し

実装時はFirestoreへの理解が浅かったのもあり、RDBっぽい設計になっているので、見直し & 新設計にマイグレーション予定
**CollectionGroup**を使えば、ある程度柔軟に設計できるかな模索中。

whereのinに取得制限があったりもするのでFirestoreは設計は、すごく重要だなと実感
https://firebase.google.com/docs/firestore/query-data/queries#limitations

## APIのrequestの型を自動生成してフロントエンドで使用

現状GraphQLに関してはgqlgenとgraphql-codegenの組み合わせで型を自動生成している。
だが、RESTful APIの方は特にやっていないので、こちらを型安全の状態にしたい。

以下のどちらかのパターンで実装しようかなと検討中

### 案1. swagger-to-tsを使って型を自動生成

swagger-to-tsでswaggerからtypeファイルを生成できるので、こちらを使用する
https://github.com/manifoldco/swagger-to-ts

ただ、これだとswaggerの方がミスっていた時に検知できないので、さらにswaggerのテストツールの**dredd**を実装する
https://github.com/apiaryio/dredd

### 案2. 現状のRESTful APIをGraphQLのmutationに移行する

mutationに移行するれば、gqlgenとgraphql-codegenの組み合わせで型を自動生成できるので、こちらを使用する
こちらの方がシンプルになりそうだけど、移行するのに時間がかかりそうな予感。

# 最後に

リリースノートを自動生成するようにしたのを、きっかけに振り返りの記事を書いて見ました。
振り返ると1年間で結構開発していたんだなーと思いました。また、なにかの区切りに振り返りの記事を書こうと思います :bow: