search
LoginSignup
0

posted at

FutureBuilder A value of type 'Object?' can't be assigned to a variable of type 'List<T?>'.

背景

Flutterにて、FutureBuilderWidgetを使っている際に出たエラーの対応メモです!
このエラーだけで1時間は余裕で浪費したので残します、、、🔥

エラー Snapshotの型が合わない

top_page.dart
// 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の型が合わない

top_page.dart
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など非同期に動く場合に使うことが多いのですが、型付き言語の意義を失いそうです)

top_page.dart
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;

諦めにはなりますが、これで動作はしたので、一時的な解決策としましょう、、、🙏
(腑に落ちないので、別の解決策をお持ちの方がいらっしゃれば
教えていただきたいです🙇)

参考文献

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0