エンジニアとデザイナー向けのSNSアプリを作りました！【会員登録が100人突破しました！感謝】

![ende_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/80b86dd1-5162-611a-6772-239a0349e74c.jpeg)
気づいたら10連休最終日！！
会社員になって中々まとまった休みが無い中、やってきたゴールデン10連休！！！

ここぞとばかり徹夜でアプリ作成に挑戦し、つい先日Appleの審査が通り本日リリースを迎えることが出来ました！！
何とも言えない達成感です。

その紹介も兼ねて、どういった技術を使用してこのアプリを作ったのかを簡単にまとめましたので読んでいただけると嬉しくて飛び跳ねます。

<h1>EndeLinkとは</h1>
Apple Storeの紹介にも記載してますが、このアプリはデザイナーとエンジニアに特化したお仕事探しアプリです。登録されたエンジニアまたはデザイナーの作品、金額、頻度で適切な仕事パートナーを探し出すことができます。
つまり、読んで字のごとくエンジニアとデザイナーを探すのにフォーカスしたSNSアプリです。

<h2>作った背景</h2>
昔、フリーランスを少しかじっていた時期があるのですが、知人のエンジニアやデザイナーさんに頼みたいけど金額面で気を使わせたり、可動日数が合わず調整が難しかったり…苦労しました…。
その頃からエンジニアやデザイナーさんを探すことに注力した良い感じのSNSをいつか作りたいなと思っていました。
現在はフリーではなく会社員ですが、会社が副業OKなので自分も仕事相手を探す機会も出てくるだろうと思い、思い切ってこの10連休を活かして開発しようと思いました。

<h1>EndeLinkはどのようにして作られたのか</h1>
![ende_board.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/fad2a1a3-fcfd-3540-2012-3c98195c3568.png)


<h2>デザイン</h2>
<img width="299" alt="スクリーンショット 2019-05-05 9.27.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/29565b86-9da7-4d90-9ee4-515a05fa6fbc.png">
色々コーディングをやってきましたが、デザインを作ったことは一度もなくセンスもないと認識しているために<a href="https://www.adobe.com/jp/products/xd.html" target="_blank">Adobe XD</a>でちゃちゃっとワイヤーフレームを作りました。
(軌道に乗れば、デザイナーさんにちゃんと制作を依頼したいです)
一番注意して作ったのが、このアプリの使用目的を明確にすることです。
そこでこのアプリは仕事パートナーを見つけるのに大事になってくる、お金や可動日数の入力を必須にし、そこをソート出来るようにしました。
またポートフォリオのURLやポートフォリオ画像も数点貼れるようにしときました。

あと、スペースはなるべく統一して作りました。
例えば上記リストページはiPhoneのファーストビューで自己紹介をMax数書いても２つのリストは最低でも見せれるように空きを調整しました。
空きをきちんと取ることにより、見た目が綺麗に見える？感じがします。
あとは実際に作りながらかなり調整していきました。

<h2>開発するプラットフォーム選び</h2>
<img width="1339" alt="スクリーンショット 2019-05-05 8.35.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/6e9a29f4-9fb1-1830-0ed5-01ea1341b177.png">
フロントエンドの技術だけでアプリが開発できるプラットフォームとして国内で開発している会社として有名な <a href="https://ja.monaca.io/" target="_blank">Monaca</a> を選びました。
フロントエンドだけのアプリ開発も徐々に選択できるようになりましたが、自分はこのMonacaのプラットフォームを利用して良かったと思うところは、日本語のドキュメントが充実している所です。
国内で開発している会社なので当たり前かもしれませんが、日頃英語のドキュメント見るのが当たり前なので、日本語のドキュメントが充実しているのは何より新鮮でしたし、大変助かりました。
あと国内産ってなぜか安心するんですよね、まー食べませんが( º﹃º｀ )…… はい。

ちなみに当たり前ですが、お問い合わせも日本語で出来るのでこれも非常に助かります。
ただしお問い合わせがテクニカルだと、お金をがっつり取られる場合があるのでそこは注意していただきたいです。

興味がある方は、下記料金プランを見ていただけると大体いくら掛かるのかが分かります。
https://ja.monaca.io/pricing.html

<h2>使用したバックエンドサービス</h2>
<img width="1184" alt="スクリーンショット 2019-05-05 8.51.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/28648ee0-b7dd-b506-2e5c-49a1fe555ce4.png">
Qiitaでもかなりの頻度で取り上げられる <a href="https://firebase.google.com/?hl=ja" target="_blank">Firebase</a> を使用しました。
Firebaseで利用したプロダクトは下記４つで、
- データベースの用意として「<a href="https://firebase.google.com/products/realtime-database/?hl=ja" target="_blank">Realtime Database</a>」
- 画像などのデータアップ先として「<a href="https://firebase.google.com/products/storage/?hl=ja" target="_blank">Cloud Storage</a>」
- その次がSNS認証として「<a href="https://firebase.google.com/products/auth/?hl=ja" target="_blank">Authentication</a>」
- あと一部アプリからデータを送信する技術を使用しているため「<a href="https://firebase.google.com/products/functions/?hl=ja" target="_blank">Cloud Functions</a>」
以上のプロダクトを用いて開発しました。
見て分かるように、Firebase一つで多種多様なプロダクトを使用できるので大変助かります。
話が少しそれるのですがFirebaseの中で色々なプロダクトが年々増えてきているのですが、最近気になるのが Google の機械学習技術を用いた「<a href="https://firebase.google.com/products/ml-kit/?hl=ja" target="_blank">ML Kit</a>」
まだベータなのですが、このAPIを利用することによテキスト認識（OCR）はもちろん顔認識を利用した技術も使用することが出来ます。
Firebaseの母体はGoogleなので、Googleで開発された技術がFirebaseでも使用できるのも嬉しいですね。

<b>・データベースのセキュリティについて</b>
Firebase Realtime Databaseでは<a href="https://firebase.google.com/docs/database/security?hl=ja" target="_blank">セキュリティ設定</a>を細かく設定することができますが、、、ここで唐突に問題です！
管理権限を持たない一般ユーザは下記 grandchild のルートには読み取りアクセスできますでしょうか？

```
{  
   "rules":{  
      ".read":false,
      "parent":{  
         "child":{  
            ".read":true,
            "grandchild":{  
               ".read":false
            }
         }
      }
   }
}
```
<br>
<br>
正解は「出来ます」
なぜならその親の child ルートで読み取りを許可したので、その権限が子に引き継かれるからです。
なので読み取り先である grandchild の読み取りを不可にしても、親のアクセス権限が適用されます。

ということは仮にトップルートで読み取りがアクセス許可されていた場合は、いくら子が読み取りアクセス不可にしても全体にアクセスできてしまうことになります。

```
{  
   "rules":{  
      ".read":true,
      "parent":{  
        "child":{  
        //アクセス出来てしまう 
        ".read":false,
            "grandchild":{  
              //アクセス出来てしまう 
              ".read":false
            }
         }
      }
   }
}
```
まーこんなことしないでしょうが。。

このようにアクセス権限は親ルートにアクセス権限をもたせた場合、それは子に影響されます。
なので今回作ったアプリではアクセス出来るルート権限ごとに細かく分けてルールを定義し、権限通りに動いてるかチェック表をつけました。
<img width="507" alt="スクリーンショット 2019-05-05 11.19.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/503f3eaa-46f0-3998-f4f6-83768e6491a5.png">
ご存知の方も多いと思いますが、Firebaseではデータのアクセス権限の確認をコンソールからシミュレートすることが出来ます。
<img width="982" alt="スクリーンショット 2019-05-05 16.36.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/7865792a-2451-b759-61e5-f049b20d7efd.png">



より詳しく知りたい方は、下記ドキュメントを見てください。
https://firebase.google.com/docs/database/security/securing-data?hl=ja#read_and_write_rules_cascade
<br>
<b>・メール認証について</b>
今回ログイン認証として<a href="https://firebase.google.com/docs/auth/web/password-auth?hl=ja" target="_blank">パスワード認証</a>と<a href="https://firebase.google.com/docs/auth/web/manage-users?hl=ja#send_a_user_a_verification_email" target="_blank">メール認証</a>を組み合わせてログインできるようにしてます。
メール認証はログイン後に下記方法で送ることが出来ます。

```
firebase.auth().currentUser.sendEmailVerification().then(function() { 
  //success
}).catch(function(error) { 
  window.alert(error); 
}); 
```
送られてきたメールのパラメータには mode や oobCode、apiKeyが付属してます。
メール認証の場合は mode は 'verifyEmail'になります。
他にもパスワード変更やメールアドレス変更などの際の mode があります。
参照 : https://firebase.google.com/docs/auth/custom-email-handler#create_the_email_action_handler_page

例えばメール認証の一例として

```
auth.checkActionCode(actionCode).then(function() { 
  //ワンタイムコード(oobCode)の確認
  auth.applyActionCode(actionCode).then(function() { 
    //メールアドレス認証を確認
  }).catch(function(error) { 
      window.alert(error); 
  }); 
}).catch(function(error) {  
  window.alert(error);
}); 
```
checkActionCodeでワンタイムコードを確認し有効であれば、applyActionCodeにてメールアドレス認証を確認することができます。

実際にメール認証されたかどうかは、Firebaseのログイン認証から一度ログアウトする必要があります。
メール認証の確認は firebase.auth().currentUser.emailVerified を使用します。

```
firebase.auth().signOut().then(function(){ 
  firebase.auth().signInWithEmailAndPassword(email, pass).then(function (info) { 
    if(firebase.auth().currentUser.emailVerified) { 
      //メールアドレス認証済み 
    } else { 
      //メールアドレス認証エラー 
    } 
  }).catch(function (error) { 
    window.alert(error); 
  }); 
}); 
```
<br>

<h2>使用したJSフレームワーク</h2>
<img width="1317" alt="スクリーンショット 2019-05-05 9.20.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/4dd02acd-07f2-4c8a-7b8d-9fa38775eedc.png">
おなじみの <a href="https://jp.vuejs.org/index.html" target="_blank">Vue.js</a>、今回SPAで開発しているためにVue.jsでコーディングさせていただきました。
またSPAを構築する際に Vue Router を使用するかと思いますが、自分は知らなかったので共有として下記方法で一つのコンポーネントに対して複数のパス(alias)を関連付けることもできます。

```
const Vue = require('vue');
const VueRouter = require('vue-router');
const Main = require('./Main');

Vue.use(VueRouter);

const routes = [{
  path: '/main',
  component: Main,
  alias: ['/page1', '/page2', '/page3']
}];
```
基本的に path と component は対になってますが、例えば alias に設定した /page1 にアクセスした際に component の Main を共有して使うことが出来ます。
ユーザーから見ると /main と /page1 は別々のURLの為に当然別のページを見てると思うのですが、裏側では共通のページを見ていることになります。


<h2>Appleからの審査について</h2>
![スクリーンショット 2019-05-05 13.48.09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/8570bcaa-eece-2ccc-c24e-c982d34fea3d.jpeg)
今回アプリの審査で2回リジェクトを食らったのですが、作ったのがSNSアプリということもあり下記基準に満たしていませんでした。
<img width="796" alt="スクリーンショット 2019-05-05 13.56.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/4cb921c3-1ee0-c8ae-b859-cac6a9e5278b.png">
これは書いてあるように、ユーザーがユーザーに対して不適切な行為をされた場合、それを防ぐ/報告手段を実装しなければならいということでした。
そこでユーザーのブロック機能と報告機能を実装して報告したところ、無事通りました。
![rb.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/208099ca-d62b-4237-bbcd-9945d710aa85.jpeg)

<h2>最後に</h2>
このEndeLinkはApple Storeに公開されようやくスタートしたばかりなので、機能拡張やデザイン改修も含めてこれからやりたいことだらけです。

あともし可能であればぜひ知り合いのデザイナーさんやエンジニアさんに紹介してもらえると有り難いです( ´^`° )

以上、読んで頂きありがとうございました。
また「いいね」を押していただけると大変励みになります(っ_ _)っ

<a href="https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=1462264543&mt=8 target="_blank">
<img width="898" alt="スクリーンショット 2019-05-06 11.25.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276563/5dc384f9-1573-6970-75c9-1ac6a110c6e6.png">
</a>
※Firebaseの料金プランの兼ね合いから、会員数によって会員登録に制限をかける可能性があります。
※今の所、このアプリは全て無料でご利用できます(広告無)

バグ報告/ご意見は、<a href="https://twitter.com/EndeLink" target="_blank">Twitter</a>からダイレクトメッセージにてご連絡ください！
※些細なことでも言っていただけると嬉しいです(´∩ω∩`)
※唯の批判などはスルーします、人としても。