🏎️

Flutter WebでDriftを使用したらハマりました。

2024/04/08に公開

はじめに

「Drift」と言うライブラリはWebでも使用できるデータ永続化ライブラリですが、Webで使用したらデータが永続化されずハマったので、ここに解決策を残しておこうと思います。

したこと

サンプルのカウンターアプリを改造して、DBにカウント値を保持するようにしました。

こちらの「Drift support in Flutter and Dart web apps.」に従って実装を進めました。sqlite3.wasmを使用する方法です。

動作の確認までは特にハマらずに実装できましたが、ブラウザを閉じてもデータが残っているかを確認したところ...

事象

カウントアップしブラウザを閉じて、もう一度実行してみるとカウント値は「0」に戻っていました。

普通にバグだと思い何度もプログラムを見直しました。print("ここまできた")も沢山仕込んで動作を見ましたが、どう見てupdateまで実行されていました。(ちなみにブレークポイントは気まぐれでヒットするのであまり使っていません。)

調査

マイグレーションや初期値の設定がバグってるんじゃないか...なんて疑って調べましたが糸口はつかめませんでした。「ブラウザの仕様かも?」と思い、indexeddbのサンプルをgithubから探して動かしてみましたが、こちらはしっかりデータが残っていました。

ふと、データの実態はどこのファイルにあるかを調べてみました。indexeddbのデータはユーザーデータ領域にあるそうですので確認しました。テストで動かしたindexeddbのサンプルのデータは残っていましたが、flutterのほうは残っていません。なぜ...

ちなみに、IndexedDBはオリジン単位で保存されます。ポート番号が変われば領域も変わります。しかし今回はあまり関係ありませんでした。

原因

Flutterのデバッグでchromeを起動するときのコマンドライン引数を確認したところ、起動するたび一時領域にユーザーデータを作成していました。このため、一度ブラウザを閉じたらもう二度とその領域は使用されません。

解決

Flutterアプリを起動するときに次のコマンドを使用しましょう。

flutter run -d web-server --web-hostname=0.0.0.0 --web-port=5555

ウェブサーバーモードで起動します。この後は普通にブラウザでアクセスすれば、作ったアプリが表示されます。

普普段通りショートカットなどからブラウザを立ち上げてください。その時のユーザーデータ領域は普段通りだと思います。再起動してもユーザーデータ領域は変わらないはずですので、カウント値も保持されているはずです。

Discussion