Flutter Firestore: Как получить данные карты из Firestore и отобразить их в виджете Flutter

# #firebase #flutter #dart #google-cloud-firestore

Вопрос:

Как я могу отобразить данные карты из коллекции в Firestore в виджете ListView при расширении? Мне нужно извлечь поля количества (int) и названия (строка) из коллекции Firestore и отобразить их в строке в моем приложении Flutter. Я получаю ошибку типа «Строка», которая не является подтипом типа » int «»индекса»

 import 'package:intl/intl.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import '../providers/orders.dart' show Orders;
import 'package:provider/provider.dart';
import 'package:ionicons/ionicons.dart';

class OrdersScreen extends StatefulWidget {
  const OrdersScreen({Key? key}) : super(key: key);
  static const routeName = '/orders-screen';

  @override
  State<OrdersScreen> createState() => _OrdersScreenState();
}

class _OrdersScreenState extends State<OrdersScreen> {
  var _expanded = false;

  @override
  Widget build(BuildContext context) {
    Provider.of<Orders>(context, listen: false);
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Theme.of(context).primaryColor,
        title: const Text(
          'Order History',
        ),
      ),
      body: StreamBuilder<QuerySnapshot>(
        stream: FirebaseFirestore.instance
            .collection('orders')
            .orderBy('date', descending: true)
            .snapshots(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: CircularProgressIndicator(),
            );
          } else {
            if (snapshot.error != null) {
              return const Center(
                child: Text('An error has occured'),
              );
            } else {
              return ListView(
                  children: snapshot.data!.docs.map((doc) {
                return Card(
                  margin: const EdgeInsets.all(10.0),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15.0),
                  ),
                  child: Column(
                    children: [
                      ListTile(
                        title: Text(
                          'R'   doc['total'],
                          style: const TextStyle(fontWeight: FontWeight.bold),
                        ),
                        subtitle: Text(
                          DateFormat('dd/MM/yyyy hh:mm a').format(
                            doc['date'].toDate(),
                          ),
                        ),
                        trailing: IconButton(
                          icon: Icon(
                            _expanded
                                ? Ionicons.chevron_up
                                : Ionicons.chevron_down,
                            color: Colors.blueGrey[900],
                          ),
                          onPressed: () {
                            setState(() {
                              _expanded = !_expanded;
                            });
                          },
                        ),
                      ),
                      if (_expanded)
                        (SizedBox(
                          height: 100.0,
                          child: ListView(
                            children: [
                              Row(
                                children: [
                                  Text(
                                    doc['orderDetails']['quantity'].toString(),
                                  ),
                                  Text(
                                    doc['orderDetails']['title'],
                                  ),
                                ],
                              ),
                            ],
                          ),
                        )),
                    ],
                  ),
                );
              }).toList());
            }
          }
        },
      ),
    );
  }
}

 

введите описание изображения здесь

Ответ №1:

Он quantity возвращается как an int , но вы передали его непосредственно a Text , который ожидает String

Попробуй:

 ListView(
    children: List.generate(
      List.from(doc['orderDetails').length,
      (i) {
       return Row(
        children: [
          Text(doc['orderDetails'][i]['quantity'].toString()),
          Text(doc['orderDetails'][i]['title'].toString())),
        ],
      );
    )
)
 

Комментарии:

1. Привет, @Josteve, спасибо за быстрый ответ. Я и это пробовал … Я все еще получаю ту же ошибку. может ли это быть из-за того, что поля находятся в массиве ? например, [0] и [1]??

2. О да, так и должно быть.

3. Это работает, но я получаю данные только из первого массива, а не из второго [1]. Когда и текст(doc[‘OrderDetails’][1][название] Я получаю ошибку RangeError (индекс): Недопустимое значение: Единственное допустимое значение-0: 1

4. Я сделал обновление, проверьте это.

Ответ №2:

Здесь orderDetails не карта<Строка, динамическая>, это список карт<Строка, динамическая><Строка, дымовая>.

Комментарии:

1. Привет @Prajeet, спасибо, что указал на это. Как я могу вместо этого сделать карту<Строковой, динамической>? вместо списка карт<Строка, dymanic>.

2. Привет @supremo , вам нужно привести doc[‘OrderDetails’] в виде списка<Карта<Строка, динамическая><Строка, динамическая>>. Как только вы получите список,вы можете использовать listview.builder или listview или столбец с детьми.