😸

【flutter】firestoreを使う

2024/04/16に公開

firestore側の設定

実装


class FirestoreDataScreen extends StatelessWidget {
  final FirebaseFirestore firestore = FirebaseFirestore.instance;

  Future<List<DocumentSnapshot>> fetchDocuments() async {
    QuerySnapshot snapshot = await firestore.collection('photos').get();
    return snapshot.docs;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Firestore Photos'),
      ),
      body: FutureBuilder(
        future: fetchDocuments(),
        builder: (BuildContext context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            }
            return ListView.builder(
              itemCount: snapshot.data?.length ?? 0,
              itemBuilder: (context, index) {
                var photoData = snapshot.data![index].data() as Map<String, dynamic>;
                print('Fetched Data: $photoData');  // 実際に取得したデータを出力

                return ListTile(
                  title: Text(photoData['title'] ?? 'Default title'),  // nullの場合のデフォルト値を設定
                  subtitle: Text(photoData['description'] ?? 'No description'),
                );
              },
            );
          } else {
            return const CircularProgressIndicator();
          }
        },
      ),
    );
  }
}

大事なこと

1.アプリとfirestoreの接続

接続はfirebaseとの接続ができていれば特にやることはなし。
要するにfirestoreと接続するから何か新しく設定がいるかというといらない

2.データ取得方法

〇コレクションの指定
QuerySnapshot snapshot = await firestore.collection('photos').get();

〇ドキュメントの指定
特になし。
→なくてもとりあえずとれるが本当は何かやるのかも?

〇フィールドの指定

body: FutureBuilder(
        future: fetchDocuments(), → コレクションの指定をする
        builder: (BuildContext context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
          if (snapshot.connectionState == ConnectionState.done) { →※参考を参照
            if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            }
            return ListView.builder(
              itemCount: snapshot.data?.length ?? 0, → このdataがドキュメントを示す
              itemBuilder: (context, index) {
                var photoData = snapshot.data![index].data() as Map<String, dynamic>; → DocumentSnapshot 型のオブジェクトに対して .data() メソッドを呼び出すことで、ドキュメントのデータを取得できます。このメソッドは、ドキュメントのフィールドとその値が含まれるマップ(Map<String, dynamic> 型)を返します。
                print('Fetched Data: $photoData');  // 実際に取得したデータを出力

                return ListTile(
                  title: Text(photoData['title'] ?? 'Default title'),  // nullの場合のデフォルト値を設定 → フィールドのキーを指定することで取得できる
                  subtitle: Text(photoData['description'] ?? 'No description'), → 同上
                );
              },
            );
          } else {
            return const CircularProgressIndicator();
          }
        },
      ),

※参考
ConnectionState は Dart の async パッケージの一部で、特に StreamBuilder や FutureBuilder などのウィジェットで非同期計算の状態を表すために使用される enum 型です。以下に各状態の説明を示します。

  1. none
    説明: 現在、どの非同期計算にも接続されていない状態を指します。
    例: FutureBuilder や StreamBuilder の future や stream プロパティが null である場合、この状態になります。つまり、まだ非同期処理が開始されていない状態です。
  2. waiting
    説明: 非同期計算に接続されており、何らかのインタラクションを待っている状態を指します。非同期処理が開始されたが、まだ最初のデータが届いていない状態です。
    例: Future が解決されるのを待っているか、Stream が最初のデータを発行する前の状態です。
  3. active
    説明: アクティブな非同期計算に接続されており、すでに一つ以上のデータを返しているが、計算が完了していない状態を指します。
    例: Stream が少なくとも一つのデータを出力したが、まだ終了していない場合(さらにデータが来る可能性がある場合)にこの状態になります。
  4. done
    説明: 非同期計算が完了した状態を指します。これ以上新しいデータが生成されないことを意味します。
    例: Future が解決された後や、Stream が閉じられた(完了した)後の状態です。

Discussion