繁体   English   中英

如何从 firestore flutter 读取数据

[英]how to read data from firestore flutter

我想从 listtile 中的 firestore 读取数据我不想使用 streambuilder 我想单独访问文档字段我尝试了这个但没有工作

class ProductList extends StatelessWidget {


  Stream<DocumentSnapshot> snapshot =  Firestore.instance.collection("listofprods").document('ac1').snapshots();


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Container(
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.black)
                ),
                child: ListTile(
                      title: Text(snapshot['name']),//here error
                ),
              )
            ],
As Per 2021 :
 streamSnapshot.data.docs

文件 doc 的更改。

@override
      Widget build(BuildContext context) {
        return Scaffold(
            body: StreamBuilder(
          stream: FirebaseFirestore.instance
              .collection('chats/XYSDa16jZBO5CUMwIk0h/messages')
              .snapshots(),
          builder: (context, AsyncSnapshot<QuerySnapshot> streamSnapshot) {
            return ListView.builder(
              itemCount: streamSnapshot.data.docs.length,
              itemBuilder: (ctx, index) =>
                  Text(streamSnapshot.data.docs[index]['text']),
            );
          },
        ));

  }

尝试这个:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';


class WeightChart extends StatefulWidget {
  @override
  _WeightChartState createState() => _WeightChartState();
}

class _WeightChartState extends State<WeightChart>  {
  dynamic data;

  Future<dynamic> getData() async {

    final DocumentReference document =   Firestore.instance.collection("listofprods").document('ac1');

    await document.get().then<dynamic>(( DocumentSnapshot snapshot) async{
     setState(() {
       data =snapshot.data;
     });
    });
 }

 @override
  void initState() {

    super.initState();
    getData();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: const Text('Weight'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            Container(
              decoration: BoxDecoration(
                border: Border.all(color: Colors.black)
              ),
              child: ListTile(
                    title: Text(data['name']),//here error
              ),
            )
          ]
        )
      ),
    );
  }
}

没有 stream 并且在一个无状态的小部件中,我用:

  • Function 首先在构建中运行
  • 这个 function 需要“async-await”才能获取数据
  • 使用 toString、get 和 data 访问所需元素。

代码:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

DocumentSnapshot snapshot; //Define snapshot

class ProductList extends StatelessWidget {
  void getData()async{ //use a Async-await function to get the data
    final data =  await Firestore.instance.collection("listofprods").document('ac1').get(); //get the data
     snapshot = data;
  }
  @override
  Widget build(BuildContext context) {
    getData(); //run the function in build
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Container(
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.black)
                ),
                child: ListTile(
                      title: Text(snapshot.data['name'].toString()),//ok no errors.
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

最后的代码可能会在 cloud_firestore 的不同版本上出现一些错误,我使用的版本是

  • cloud_firestore:^0.13.7
  • firebase_core: ^0.4.5

和其他错误是一个红色屏幕,文本上有一些 null,这是用 FutureBuilder 修复的,而不是直接调用 de 数据,通过这种方式:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class ProductList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Future<String> data2() async {
      var data1 = (await Firestore.instance
              .collection('listofprods')
              .document('ac1')
              .get())
          .data['name']
          .toString();
      return data1;
    }
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Container(
                decoration:
                    BoxDecoration(border: Border.all(color: Colors.black)),
                child: ListTile(
                  title: FutureBuilder(
                    future: data2(),
                    builder: (BuildContext context, AsyncSnapshot snapshot) {
                      print(snapshot.data);
                      return Text(snapshot.data);
                    },
                  ), //ok no errors.
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

你可以使用StreamBuilder

StreamBuilder<QuerySnapshot>(
  stream: Firestore.instance.collection('books').snapshots(),
  builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
    if (snapshot.hasError)
      return new Text('Error: ${snapshot.error}');
    switch (snapshot.connectionState) {
      case ConnectionState.waiting: return new Text('Loading...');
      default:
        return new ListView(
          children: snapshot.data.documents.map((DocumentSnapshot document) {
            return new ListTile(
              title: new Text(document['title']),
              subtitle: new Text(document['author']),
            );
          }).toList(),
        );

这适用于 FlutterFire! 我使用了 DocumentSnapshotawait

通过使用DocumentSnapshot ,您可以获得包含文档字段及其值的文档。

DocumentSnapshot 包含从 Cloud Firestore 数据库中的文档读取的数据。 可以使用 data() 或 get() 提取数据以获取特定字段。

关键字await将等待任何异步函数完成。

您可以使用 await 关键字来获取异步表达式的完成结果。 await 关键字仅在异步 function 中有效。

import 'package:cloud_firestore/cloud_firestore.dart';

final db = FirebaseFirestore.instance;

// Get document with ID totalVisitors in collection dashboard
await db.collection('dashboard').doc('totalVisitors').get()
  .then((DocumentSnapshot documentSnapshot) {
                            
    // Get value of field date from document dashboard/totalVisitors
    firestoreDate = documentSnapshot.data()['date'];

    // Get value of field weekOfYear from document dashboard/totalVisitors
    firestoreWeek = documentSnapshot.data()['weekOfYear'];

  }
);

flutter中对 stream 使用Streambuilder

StreamBuilder<DocumentSnapshot>(
     stream: Firestore.instance.collection("listofprods").document('ac1').snapshots(),
     builder: (context, snapshot) {
       if (!snapshot.hasData) return LinearProgressIndicator();

       return _buildList(context, snapshot.data.documents);
     },
   );
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class DataFetch extends StatefulWidget {
  const DataFetch({Key key}) : super(key: key);
  @override
  _DataFetchState createState() => _DataFetchState();
}
class _DataFetchState extends State<DataFetch> {
  List<Model> list=[];
  void fetchData()async{
    var data=await FirebaseFirestore.instance.collection("Items").get();
    for(int i=0;i<data.docs.length;i++){
      Model model=Model(data.docs[i].data()['title'], data.docs[i].data()['price'],data.docs[i].data()['imageURL'],data.docs[i].data()['desc'], data.docs[i].data()['seller']);
      list.add(model);
    }
  }


  @override
  void initState() {
    super.initState();
    fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          child: list.length==0? Center(child: Text("No Post")):ListView.builder(itemCount: list.length,
            itemBuilder:(_,index){
              return MyUI(list[index].title, list[index].url, list[index].price, list[index].desc, list[index].seller);
            },
          ),
        ),
      ),
    );
  }
  Widget MyUI(String title,String url,String price,String desc,String seller){
    return Container(
      child: Column(
        children: [
          Text(title),
          Image.network(url),
          Text(price),
          Text(desc),
          Text(seller)
        ],
      ),
    );
  }
}

class Model{
  String title,price,url,desc,seller;
  Model(this.title,this.price,this.url,this.desc,this.seller);
}

使用null Safety更新 2023


有2种方式:

1.StreamBuilder

当你想不断地监听变化,并希望数据在没有热重载/重启的情况下得到更新

2.未来建造者

当你只想获取文档一次,而不需要一直监听文档的变化时。


StreamBuilder

1. 多份文件

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder<QuerySnapshot>(
          stream: FirebaseFirestore
                  .instance.
                  .collection('users') // 👈 Your desired collection name here
                  .snapshots(), 
          builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
            if (snapshot.hasError) {
              return const Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Text("Loading");
            }
            return ListView(
                children: snapshot.data!.docs.map((DocumentSnapshot document) {
              Map<String, dynamic> data =
                  document.data()! as Map<String, dynamic>;
              return ListTile(
                title: Text(data['fullName']), // 👈 Your valid data here
              );
            }).toList());
          },
        ),
      ),
    );
  }

2. 单一文件

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
          stream:  FirebaseFirestore
                   .instance
                   .collection('users')
                   .doc(FirebaseAuth.instance.currentUser!.uid) // 👈 Your document id change accordingly
                   .snapshots(), 
          builder:
              (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
            if (snapshot.hasError) {
              return const Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Text("Loading");
            }
            Map<String, dynamic> data =
                snapshot.data!.data()! as Map<String, dynamic>;
            return Text(data['fullName']); // 👈 your valid data here
          },
        ),
      ),
    );
  }

未来建造者

1. 多份文件

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: FutureBuilder<QuerySnapshot>(
        future: FirebaseFirestore
                .instance
                .collection('users') // 👈 Your collection name here
                .get(), 
        builder: (_, snapshot) {
          if (snapshot.hasError) return Text('Error = ${snapshot.error}');
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Text("Loading");
          }
          return ListView(
              children: snapshot.data!.docs.map((DocumentSnapshot document) {
            Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
            return ListTile(
              title: Text(data['avatar']), // 👈 Your valid data here
            );
          }).toList());
        },
      )),
    );
  }

2. 单一文件

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
        future: FirebaseFirestore.instance
            .collection('users')
            .doc(FirebaseAuth.instance.currentUser!.uid)  // 👈 Your document id change accordingly
            .get(),
        builder: (_, snapshot) {
          if (snapshot.hasError) return Text('Error = ${snapshot.error}');
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Text("Loading");
          }
          Map<String, dynamic> data = snapshot.data!.data()!;
          return Text(data['fullName']); //👈 Your valid data here
        },
      )),
    );
  }

有2种方式:

1.StreamBuilder

当你想不断地监听变化,并希望数据在没有热重载/重启的情况下得到更新

2.未来建造者

当你只想获取文档一次,而不需要一直监听文档的变化时。


StreamBuilder

1. 多份文件
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder<QuerySnapshot>(
          stream: FirebaseFirestore
                  .instance.
                  .collection('users') // 👈 Your desired collection name here
                  .snapshots(), 
          builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
            if (snapshot.hasError) {
              return const Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Text("Loading");
            }
            return ListView(
                children: snapshot.data!.docs.map((DocumentSnapshot document) {
              Map<String, dynamic> data =
                  document.data()! as Map<String, dynamic>;
              return ListTile(
                title: Text(data['fullName']), // 👈 Your valid data here
              );
            }).toList());
          },
        ),
      ),
    );
  }
2. 单一文件
 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
          stream:  FirebaseFirestore
                   .instance
                   .collection('users')
                   .doc(FirebaseAuth.instance.currentUser!.uid) // 👈 Your document id change accordingly
                   .snapshots(), 
          builder:
              (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
            if (snapshot.hasError) {
              return const Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Text("Loading");
            }
            Map<String, dynamic> data =
                snapshot.data!.data()! as Map<String, dynamic>;
            return Text(data['fullName']); // 👈 your valid data here
          },
        ),
      ),
    );
  }

未来建造者

1. 多份文件
@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: FutureBuilder<QuerySnapshot>(
        future: FirebaseFirestore
                .instance
                .collection('users') // 👈 Your collection name here
                .get(), 
        builder: (_, snapshot) {
          if (snapshot.hasError) return Text('Error = ${snapshot.error}');
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Text("Loading");
          }
          return ListView(
              children: snapshot.data!.docs.map((DocumentSnapshot document) {
            Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
            return ListTile(
              title: Text(data['avatar']), // 👈 Your valid data here
            );
          }).toList());
        },
      )),
    );
  }
2. 单一文件
 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
        future: FirebaseFirestore.instance
            .collection('users')
            .doc(FirebaseAuth.instance.currentUser!.uid)  // 👈 Your document id change accordingly
            .get(),
        builder: (_, snapshot) {
          if (snapshot.hasError) return Text('Error = ${snapshot.error}');
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Text("Loading");
          }
          Map<String, dynamic> data = snapshot.data!.data()!;
          return Text(data['fullName']); //👈 Your valid data here
        },
      )),
    );
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM