how to read data from firestore flutter

无人久伴 提交于 2020-12-10 06:59:38

问题


i want to read data from firestore in a listtile i dont want to use streambuilder i want to access the documents field individually i try this but not working

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

回答1:


Try this:

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



回答2:


you can use 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:


Use Streambuilder for stream in flutter

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

       return _buildList(context, snapshot.data.documents);
     },
   );



回答4:


without stream and in a stateless widget, I made it with:

  • Function running at first in build
  • This function need to be "async-await" in order to get data
  • Use of toString, get and data for access the desire element.

code:

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

the last code maybe gets some errors on diferents versions of cloud_firestore the version i use is

  • cloud_firestore: ^0.13.7
  • firebase_core: ^0.4.5

and other error is a red screen with some null on text, this is fix with a FutureBuilder instead to call directly de data, in this way:

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



回答5:


This works in FlutterFire! I used DocumentSnapshot and await.

By using DocumentSnapshot, you can get the document including document fields and its values.

A DocumentSnapshot contains data read from a document in your Cloud Firestore database. The data can be extracted with data() or get() to get a specific field.

The keyword await will wait until any async functions are finished.

You can use the await keyword to get the completed result of an asynchronous expression. The await keyword only works within an async 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'];

  }
);


来源:https://stackoverflow.com/questions/59529177/how-to-read-data-from-firestore-flutter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!