100 App Team Blog

半径100メートルのユーザーと気軽に匿名チャットができるアプリ「100(ワンハンドレッド)」のなかのひとたちによるテック x UI/UXデザイン x 企画あれこれブログ。プロダクトをグロースさせる試行錯誤の日々を記録。

駆け出しエンジニアが、データの同期を取るのに苦戦した話~前編~

初めまして!

ロックミー インターンのJyoです!

「100」アプリのエンジニアとして、日々奮闘しています。

 

「100」の企画が始まったのは、2017年10月6日。

当時の私は、Swiftを勉強し始めたばかりで、画像をクルクルさせたり、ボタンを押して画面を遷移させるので精一杯の The 初心者...

「どうやって位置情報を取得する?」とか「データベースの仕組みは?」という質問をされても、「知らないです...」というレベルでした。

 

そこから実際に動かしながら勉強していくこと一年。2018年12月7日に「100」はリリースされました!

 

私の記事では、開発していく中で初めてやったからこそ、ぶつかった壁について、自分なりの解決方法と共に書いていこうと思います!

 

それでは、1つ目のぶつかった壁です!

 

▶︎ 壁の1: 近くの人の数を同期せよ!

100m以内の人と会話を楽しむこのアプリですが、このアプリをより楽しんでもらうために、ある機能が入っています。

 

それがこちら!

f:id:Jyo:20190125115612p:plain

図1: 近くの人を表示するインジゲーター

起動してすぐに、100m以内に何人いるのかをサーバーと同期し、表示してくれる機能です!

 

この機能を作る上で、ぶつかってしまった壁は、タイトルにも書いた[同期]の部分でした。

 

 

なぜ同期が難しかったのか

近くで見ている人をログインユーザー*1

近くにいる人の数をログインユーザーとログアウトユーザー*2の総数

とするなら、それぞれの数を適切なタイミングで持ってくるだけ。終わり!

 

...だったのですが、問題が2点ありました。

一つ目が、100m以内のユーザーを取得する必要があるということ。

二つ目が、データベース通信の制限でした。

 

1. 100m以内のユーザー取得の問題

これがどうして悩んでしまったのか。図を見て解説していきます。

図中の左にいる黒色の男性をAさん。右側の黒色女性をBさんとします。

f:id:Jyo:20190125130203p:plain

図2: 日本で区切られていた場合

もし、取得するデータが、日本にいるユーザーだったら。

Aさんが取得するデータも、Bさんが取得するデータも、自分を入れて9人になるはずです。

もし、AさんとBさんが違うデータを取得するとしたら、AさんかBさんが日本以外の国に旅行したときだけですね。

 

では、100m以内のユーザーを取得する場合はどうでしょうか?

 

f:id:Jyo:20190125131700p:plain

図3: 100mだった場合

 

Aさんの100mの円にいるのは3人 、Bさんの100mにいるのは4人とデータが変わってきます。

つまり、問題だったのはユーザー毎に取得するデータが違うということでした。

 

f:id:Jyo:20190125135213p:plain

図4: データ同期の解決策1

この問題は、図のようにサーバー側に各ユーザーの位置情報(緯度・経度)を保存し、それを各ユーザーが読み込み、100m以内かどうかで処理をすれば、問題なくデータが出そうです。

 

しかし、そう考えたときに、また問題が出てきました...

それが、データベース通信の制限です。

 

 

2. データベースの通信制限

今回使用しているデータベースは、Googleが提供している

Firebase Realtime Databaseです。(以下RDBと略します)

firebase.google.com

 

名前の通り、リアルタイムで同期が取れて、通信するデータの量も少なく、チャットアプリには最適と判断して使用しています。

 

どんな制限があるかの詳細は、こちらをご覧ください。

  

では、なぜ通信するデータが少ないのに制限がかかってしまうのか。

それは、図4の2に書いてある、全てのユーザーの位置情報を受信というのが問題でした。

 

今回使用しているRDBのデータの保存方法が少し独特でした。

私が知っているデータベースとの違いはこんな感じでした。

 

f:id:Jyo:20190125151320p:plain

図5: 想像と違うデータベース

理想では、ExcelやNumbersのような表みたいになっていて、データのソート*3や特定のデータの抽出が楽なものだと思っていました。

 

しかし、実際にRDBを使い始めてみると、植物の根っこのようでした。

一つのデータでのソート機能はついてはいましたが、複数データでのソートができず、

緯度と経度をそれぞれ比較し、ユーザーから100m以内のデータだけを取り出すということがサーバーだけでは不可能でした。

 

話を少し戻しまして、通信するデータが少ないと言っていましたが、データの取り出し方でデータの通信容量が変わってきます。

 

例えば、あなたが欲しいデータは根っこの先端にあるとします。

そのときにデータを取る方法は極端にあげると、2つあります。

根を全て掘り起こすか、先端だけ切り取るかです。

 

f:id:Jyo:20190125153320p:plain

図6: RDBでのデータ通信容量

この場合データの通信容量が大きいのは、図で見てわかる通り、根を全てとった場合です。

つまり、データの量を抑えるには、出来るだけ根っこの先端に保存し、かつ、切り取りやすくする必要があります。

 

しかし、現段階では、ログインしているユーザーの、緯度と経度を比較して100m以内のデータを取得するには、ログインしているユーザーの根っこを全て切る必要があるので、とても多くのデータ通信が発生してしまいます。

それを全てのユーザーがやると、サーバーがパンクするのは間違い無いでしょう。

 

 

と、長々と問題について説明したところで、今回は終了したいと思います。

 次回はこの2点の問題を解決した方法を書いていきたいと思います!

 

最後まで読んでいただき、ありがとうございました!

また、お会いしましょう!

 

以上 Jyoでした!

 

 

*1:現在、100を使用しているユーザー

*2:アプリを入れていて、現在は利用していないユーザー

*3:データを並び替えること