FirebaseのDBアクセス多重問題の回避策 2024/04/06
Hot Restart問題で生産性低下が続いている。
以前にも書いたが、ホットリスタートをした回数分だけfirebaseのDBアクセスが重複するようになり、下記例外が発生する
Error: TypeError: Instance of '_Exception': type '_Exception' is not a subtype of type 'JavaScriptObject'
たとえば3回ホットリスタートすれば3回連続で例外が発生するようになるという具合。
どうもHotRestartした時にStreamControllerがcloseされないことが問題に思える。
ところが調べてみるとかなり根深い問題のようだ。
いくつも関連する報告があり、2017年くらいからオープンのままのチケットもある。全部読んだわけではないがこのあたりか。
- [cloud_firestore] streams not closed on hot restart on [Web] #4756
- [Auth, Firestore, Storage, …] Event Listeners are Not Properly Disposed on Web Hot Restart across all plugins. #7064
- [doc] Explain how hot-restart works and why deactivate (dispose) not called on hot restart #69949
- Do plugins need to know about hot reload and hot restart? #10437
- Add hot restart hooks to support dart:ffi #75528
- このなかの [Auth, Firestore, Storage, …] Event Listeners are Not Properly Disposed on Web Hot Restart across all plugins. #7064 でworkaroundが載っていた。
class _FirebaseStream<T> extends Stream<T> {
final Stream<T> inner;
_FirebaseStream(this.inner);
// during regular execution this variable doesn't change, only hot restart could affect it
static final _timestamp = DateTime.now();
@override
StreamSubscription<T> listen(void Function(T event)? onData, {Function? onError, void Function()? onDone, bool? cancelOnError}) {
StreamSubscription<T>? subscription;
final timestamp = _timestamp;
subscription = inner.listen(
(event) {
if (timestamp == _timestamp) {
onData?.call(event);
} else {
subscription?.cancel();
}
},
onError: (error) {
if (timestamp == _timestamp) {
onError?.call(error);
} else {
subscription?.cancel();
}
},
onDone: onDone,
cancelOnError: cancelOnError,
);
return subscription;
}
}
extension FirebaseStreamWorkaround<T> on Stream<T> {
Stream<T> get usingFirebaseWorkaround {
if (kReleaseMode) {
return this;
} else {
return _FirebaseStream(this);
}
}
}
ただ自分の場合はこれでうまく行かなかったので、仕方が無く画面に「Streamをクローズだけのボタン」を置くことにした。
面倒だがこのボタンをHot Restart前に押せば不具合の発生は抑えられる。
これとは別に「ブラウザをリロードする」という方法もあるのだが、接続が切れたり再読み込みに時間がかかったりとどうも使い勝手が悪かったので、「手動でStreamクローズボタン」で当面は乗り切るしか無さそう。
ちなみに私はついhot restartを「hot reload」と呼んでしまいがちなのだが、flutter webだとホットリロードは無くてホットリスタートのみとのこと。
引き続き細かな不具合修正。
1アイディアあたりの文字数の制限 2024/04/07~04/08
1アイディアの文字数が多い場合に制限するようにした。
これまでは特に制限をしていなかったが、以下の理由から文字数制限を設定。
- 1つのTextField内の文字数があまり多くなると描画パフォーマンスが悪化する
- 文字数が多ければその分DBへの反映にコストがかかる
- 1つのアイディアに文字だけで数メガ入れられて、本来の用途と違う形のデータ置き場にされると困る
肝心の文字数制限はひとまず2000文字にした。アイディアレーンは基本1アイディア1行なので、実用的には数百文字もあれば十分だと思う。とはいえ余裕を持ってそのくらいにしておいた。
その他の修正としては、アイコンを改善したり、アイディアにフォーカスしたときのホバーアイコンの挙動を調整したりした。
※開発日記は当時の記録をもとに作成し、必要に応じて加筆・補足しています
この記事はアイディア整理ソフト「idea Lane」の開発記録です
↓どなたでも、ユーザ登録だけで無料ですぐに使えます↓
テキストベースの思考整理ツール「idea Lane」
コメント