😸

Flutter✖️Firestore ローカルからクエリしてみたって体験とその感想。マジ便利。

2023/05/18に公開

最近、自分でもビビるくらいコーディングして
逆にタイピング遅くなった気がします。

(...)

さて、そんなタイピングが遅くなった訳ですが、
今回は、Firebaseのローカルデータについて書きます。

意外と知られてないかも...??

僕もここ最近やっと使い始めました。

こいつ(Firebase様)サーバーを経由して取得したデータをローカルで保存してたんです。まさかの。
知ってました??

しかも、アプリをキルしたら消えるかと思いきや、消えてないんですよね〜。謎に。
どうやら、ガチでローカル上で持ってるっぽくて、アプリをアンインストールして初めてデータが消えてたのを確認してびっくりしました。

こんなん使い始めて2年弱ですが、初めて知った。
ワロタニエン。
ぴえん。
ワニワニワニワー。

使い勝手

ローカルに保存されてるなら、毎回ローカルから引っ張ってきたら良いやん!
めっちゃ節約できる、ラッキー!

って思った、そこの過去の僕。
気を付けなはれや。
そこが意外な落とし穴やから。

まぁ、でも、そうなる気持ちは凄く分かる。

それこそ riverpod2 になってからはデフォルトで autoDispose が追加されてるから
キャッシュしてたデータやけどサーバーから再取得しなあかん。って事になりがちよね。
じゃあ、思い切って keepAlive : true にするかと思っても、重くなりそうで心配。。。

それはそう。そう思うのが正解かも。

なので、ローカルに保存されてる過去のデータを取得するのが良い!
って結論に一旦なると思う。

ですが、ここに1つ穴があります。

それは、ローカル上では最新のデータだったとしても
Firebaseサーバーで保存されてるデータも最新だとは限らないという事です。

要は、Firebase上では更新されてるけど
ローカル上で残ってるデータは古いデータになってる可能性がある
っていうことや。

UpdatedAt がビビるくらい重要

結局のところ、何が言いたいか
更新日付を追って再取得する必要があるという事。

最新のデータが不要なら別にする必要ないけど
古いデータをずっと持っててもしょうがないし、
むしろ場合によってはその古いデータだと困る場合があるよね。

個人的にやった事としては、

  1. ローカルから最新のデータを1つだけ取得する
  2. その最新データを基準にサーバーから新しいデータを取得する
  3. ローカルに更新されたデータが入ってるから、そのローカルデータを全て取得する

こんな感じのノリかな。
最終的にローカルから取得するデータだから重複する心配がなく便利よ。

何かもう1つくらい書き残したい

ここの画面で、あそこのデータ使いたい・・・
でも、サーバーからデータ取得するのは勿体無い。
だけど、あそこのview modelからデータを取るのは設計的にも、、、

って思う場面があるかもしれないですよね。
っていうか、僕は結構ある。

これをローカルのデータが解決してくれる!

でも、最新のデータではない可能性が十分にあるから
そこだけは気を付ける必要があるからね。

特にEC系だと売り切れとかのステータスかな
あとは、Webでは削除してるけどモバイルでは削除されてないカートとかね。

メリット

ローカルのデータを活用することで何がお得かと言うと
最新のデータを取得する数が減ったという事かな。

ECとかだと、ショップページのメニューデータとか。
毎回開くたびに20,30とか取得してたら大変やけど、
ローカルから取得 + UpdatedAtが更新されてるデータだけ取得
で済むからサーバーを経由して取得する数は減るはず。

ぶっちゃけメニューデータとかは量取得する必要あるけど
更新される事ってそんなにないやろうし。

1購入ずつupdatedAtが更新されてウザい場合は
updatedAtとかにも種類をつけて、menuCountUpdatedAtとかsoldOutUpdatedAtとか付けたら良いのかも(この辺は自分で考えてみて)

デメリット

ローカルから取得できるならデータさえあればサーバーから取得しなくて済むやんって思ってしまう
過去の僕が現れるだろうと言う事。

データは常に更新されてると思って良いので、
ローカルにデータがあるからといって慢心をしないことやね。

まぁ、エラーチェックとかしたら明らかに新しいデータが必要やのにデータが無いみたいな状況に陥って
ほぼ100%どこかで気付くと思うけどね。

あとは、ローカルから取得と言っても結局は非同期処理なので
0.1sくらい取得するのに時間がかかってしまう。

その場合、上であげた方法を使用すると非同期処理が3回

  1. ローカル
  2. サーバー
  3. ローカル

となるから注意が必要。

こんな事を1つの画面で、2回3回と描画する前にやってしまうと
普通にローディング時間が1s〜2sくらいかかる場合があるかもしれない。

メモ
・Future.wait などで並行処理したらだいぶ減るかも
・先にローカルデータだけ取得して表示、その後に0.2,0.3秒くらい使ってサーバーから再取得も良いかも

なので、この辺は描画のタイミングとかとも考慮しながらどのタイミングで
ローカルのデータを更新するべきなのか、とかを考えてやってもらえると良いかとmm

あと強いて言うなら、サーバー処理だけだったのが
ローカルからもデータを取得する必要があると言う点で
普段はアロー関数だけで終了してたコードが一気に増えると言う点ですかね。

まぁ、しゃーない。諦めろ。

まとめ

ローカルデータは使えれば強い。けど、慣れるまで1,2日かかる。

あと、ユーザーがいない最初から実装する必要はない。
パパッとリリースを目的とするなら全然後で良さそう。

Discussion