如何从Firestore Flutter中读取数据

时间:2019-12-30 10:19:03

标签: firebase flutter dart google-cloud-firestore

我想从列表库中的firestore中读取数据,我不想使用streambuilder,我想单独访问documents字段,但是尝试了

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
                ),
              )
            ],

6 个答案:

答案 0 :(得分:6)

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']),
            );
          },
        ));

  }

答案 1 :(得分:1)

尝试一下:

interface TestFunction {
        (fn: Func): Test;
        (fn: AsyncFunc): Test;
        (title: string, fn?: Func): Test;
        (title: string, fn?: AsyncFunc): Test;
        only: ExclusiveTestFunction;
        skip: PendingTestFunction;
        retries(n: number): void;
    }

答案 2 :(得分:1)

您可以使用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(),
        );

答案 3 :(得分:0)

没有流,并且在无状态小部件中,我用以下方法实现了

  • 函数首先在构建中运行
  • 此功能需要“异步等待”才能获取数据
  • 使用toString,get和data来访问desire元素。

代码:

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

另一个错误是红屏,文本上带有一些空值,这是通过FutureBuilder解决的,而不是通过这种方式直接调用数据:

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.
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

答案 4 :(得分:0)

这在FlutterFire中有效!我使用了DocumentSnapshotawait

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

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

关键字await将等待所有异步功能完成。

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

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'];

  }
);

答案 5 :(得分:0)

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);
}