背景
Flutterにて、FutureBuilder
Widgetを使っている際に出たエラーの対応メモです!
このエラーだけで1時間は余裕で浪費したので残します、、、🔥
エラー Snapshotの型が合わない
// ScaffoldのAppbar部分まで省略
body: StreamBuilder<QuerySnapshot>(
stream: RoomFirestore.joinedRoomSnapshot,
builder: (context, streamSnapshot) {
if (streamSnapshot.hasData) {
return FutureBuilder(
future: RoomFirestore.fetchJoinedRooms(streamSnapshot.data!),
builder: (context, futureSnapshot) {
if (futureSnapshot.hasData) {
- List<TalkRoom?> talkRooms = futureSnapshot.data;
return ListView.builder(
// listの表示数
itemCount: talkRooms.length,
// 残りの重要でないWidget情報は省略
エラーが出た箇所にDiffで赤色のマーカーをつけています。
A value of type 'Object?' can't be assigned to a variable of type 'List<TalkRoom?>'.
型が合わないぞ、と言われます。
このエラーを見た結果、FutureBuilder自体に型をつければ
future
プロパティを介してSnapshotの型を変えることができるので
型をつけてみますと、次のエラーになりました。
エラー futureの型が合わない
body: StreamBuilder<QuerySnapshot>(
stream: RoomFirestore.joinedRoomSnapshot,
builder: (context, streamSnapshot) {
if (streamSnapshot.hasData) {
return FutureBuilder<List<TalkRoom?>>(
- future: RoomFirestore.fetchJoinedRooms(streamSnapshot.data!),
builder: (context, futureSnapshot) {
if (futureSnapshot.hasData) {
List<TalkRoom?> talkRooms = futureSnapshot.data!;
return ListView.builder(
// listの表示数
itemCount: talkRooms.length,
今度は、以下のようなエラーが出ました。
The argument type 'Future<List<TalkRoom>?>' can't be assigned to the parameter type 'Future<List<TalkRoom>?>?'.
future
プロパティが謎の余計な?
をつけ、型が合わなくなりました。
また、メソッド側の型をFuture<List<TalkRoom>?>?
に合わせると
The argument type 'Future<List<TalkRoom>?>? (where TalkRoom is defined in /Users/chat_firebase_app/lib/model/talk_room.dart)' can't be assigned to the parameter type 'Future<List<TalkRoom>?>? (where TalkRoom is defined in /Users/chat_firebase_app/lib/pages/talk_room.dart)'.
もっとえぐいエラーが出ました。
解決策
今回はWidgetの仕様として回避できる気がしないエラーなので、
静的型付き言語としてはあるまじきdynamic
(TSのAny的な型)を使います。
(APIなど非同期に動く場合に使うことが多いのですが、型付き言語の意義を失いそうです)
body: StreamBuilder<QuerySnapshot>(
stream: RoomFirestore.joinedRoomSnapshot,
builder: (context, streamSnapshot) {
if (streamSnapshot.hasData) {
// FutureBuilder<List<TalkRoom?>>ではfutureプロパティが変な解釈してバグる
return FutureBuilder(
future: RoomFirestore.fetchJoinedRooms(streamSnapshot.data!),
builder: (context, futureSnapshot) {
if (futureSnapshot.hasData) {
+ dynamic talkRooms = futureSnapshot.data;
諦めにはなりますが、これで動作はしたので、一時的な解決策としましょう、、、🙏
(腑に落ちないので、別の解決策をお持ちの方がいらっしゃれば
教えていただきたいです🙇)
参考文献