質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

Q&A

解決済

1回答

1367閲覧

flutter firestoreから取得したデータをTextで表示させようとするとエラーが出る。

kaji_isaki

総合スコア8

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

0グッド

0クリップ

投稿2022/07/19 15:04

ネットの情報を参考にほぼコピペでコードを書いたのですが、文法のエラーは出ていないものの、該当のページを開くと次のエラーが出てきます。「RangeError (index): Invalid value: Valid value range is empty: 0」

下の画像の「日本」コレクションにある「title」フィールドの値をすべてリストに入れてTextで表示したいと考えています。

イメージ説明

Dart

1class ProductModel { 2 String title; 3 ProductModel( 4 this.title, 5 ); 6} 7 8class ProductListModel extends ChangeNotifier { 9 List<ProductModel> products = []; 10 11 Future getProducts() async { 12 var collection = await FirebaseFirestore.instance.collection("日本").get(); 13 products = 14 collection.docs.map((doc) => ProductModel(doc['title'])).toList(); 15 this.products = products; 16 notifyListeners(); 17 } 18}

Dart

1class Nihon extends StatefulWidget { 2 3 State<Nihon> createState() => _NihonState(); 4} 5 6class _NihonState extends State<Nihon> { 7 8 Widget build(BuildContext context) { 9 return Scaffold( 10 appBar: AppBar( 11 title: Text("日本"), 12 ), 13 body: ChangeNotifierProvider( 14 create: (_) => ProductListModel()..getProducts(), 15 child: Consumer<ProductListModel>( 16 builder: (context, model, child) { 17 final products = model.products; 18 return SafeArea( 19 child: Column(children: <Widget>[ 20 Text(products[0].title), 21 Text(products[1].title), 22 ]), 23 ); 24 }, 25 ), 26 ), 27 ); 28 } 29}

エラーを解決するためには上のコードにどのような修正が必要でしょうか?
力を貸していただきたいです。
よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

エラーメッセージから見るに、productsにデータがないからエラーになっていると思われます。
まず正しくデータが取得できている確認してみては。
具体的には、final products = model.products;の後にdebugPrint等でproductsの内容を表示してみるとか。

次に、getProductsのリターンがFutureなのでそれを実行した結果を利用するにはFutureBuilderを使う方が正統かも。この部分は、SafeAreaをFutureBuilderでラッピングをする形にする。
FutureBuilderを使わないのであれば、以下の様な感じかな。現在確定している情報でTextを構築している。
収集が完了したらnotifyListenersで再度構築が走る。
(即興で書いたので文法エラーがあったら適時直してください)

dart

1final products = model.products; 2final widgets = List.generate(products.length, (i) => Text(products[i].title)); 3return SafeArea( 4 child: Column(children: widgets,), 5);

多分、create: (_) => ProductListModel()..getProducts(),でproductsの中身を取り出そうとしているけど、SafeAreaを作成するときまでにgetProductsの処理が完了しておらずproductsがempty何だと思う。そのため[0]とデータがある前提で実装しているのでエラーが出ている。

上記に関しては、実行環境がないのであくまでソースコードから見た想像だけど。

後、FlutterでFirestoreを扱うならFlutterFireが1次情報になると思うので、サンプル等はそちらを参照したほうがいいです。それ以外は2次情報以下になり、それこそ正しくない情報も含まれている可能性があります。
ちなみにFlutterでFirebaseのデータを取り扱うサンプルでは、StreamBuilderで取り出し使用しています。

最後に。
今回の実装だけであればChangeNotifier関連を使う必要性が感じられない。FutureとかStreamの意味が分からずデータ収集完了をChangeNotifierを使って知らせるというだけであれば、斜め上の実装方法に感じる。
コピペ元が、サーバーからの通知なども含めたもう少し複雑なクラスで、ChangeNotifierをFlutterへの通知の手段として使っていると信じたい。

投稿2022/07/20 00:54

ta.fu

総合スコア1664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaji_isaki

2022/07/20 16:37

返信遅れて申し訳ございません。 親切な回答、心より感謝致します。 頂いた回答を踏まえて「StreamBuilder」や「ChangeNotifier」を調べてみたところ、結局私がやりたいのは「firestoreにあらかじめ入っているデータをflutter内でString型の変数や、リストに格納する」ことだと気が付きました。(firestoreから取得した文字列にflutter内で操作を加えたいから) そのためにはあらかじめ用意したfirestoreのドキュメントと同じデータ構造のクラス(これをモデルという?)を用意してそこにfirestoreのDocumentReference型の値を入れていくという感じになるということでしょうか? またそれはどのような方法で可能なのでしょうか? 教えて頂いたFlutterFireも読んでみたのですが、なにが私のしたいことにあっているのかよく分からず… 再びの質問になってしまい大変申し訳無いのですが可能であれば回答いただければ幸いです。 意味不明な質問になっている可能性が大いにありますが… 最後になりますが恥ずかしながらdebugprintというものの存在を初めて知りました。とても役に立ちますね。教えて頂きありがとうございました。
ta.fu

2022/07/20 20:23

firestore(Cloud Firestore)からのデータ取り出しは、それこそFlutterFireの中に例題含めドキュメントとして記載されています。そこから引き出したデータの加工はDart言語の理解の範疇でできると思います。 ページとしては https://firebase.flutter.dev/docs/firestore/usage/ になるのかな。 後はそれ用のAPIとして https://pub.dev/packages/cloud_firestore 。 私は使ったことはないのでこれ以上の回答はしづらいです。特に質問内容が「この部分が分からない」というのではなく「全部わからないので教えてください」に見えてしまうので。 後teratailの過去の回答を見てもcloud_firestore関連の回答は少ないように見えます。 多分回答者が実行できる環境を整えるための情報が不足するのが多いので、回答しづらいんだと思います。 もし回答してもらいたいのであれば、簡単に再現できるように質問を工夫する必要があるんだと思います。 大抵はそういう工夫をしている段階で原因が分かったりするもんですが。
kaji_isaki

2022/07/21 07:53

返信ありがとうございます。 確かに何がわからないのかもあやふやといった部分もあって、本当におっしゃる通り、丸投げな質問になってしまっているなと反省しております…。とりあえずflutterfireからもう少し丁寧に読み進めていきます。 今後はもっと自分の中で試行錯誤をしてどこのどういう部分が分からないかを明確にしてから質問させて頂こうと思います。 この度は多くの情報や気付きを与えて頂き本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問