从 Firebase FireStore 获取图像到轮播 Flutter

问题描述

大家好,我指的是 YouTube 视频中关于在 Flutter 移动应用程序中从 firestore 显示轮播图像的视频。但是有一些我无法解决的问题。希望任何人都可以帮助我完成我的学校项目。谢谢!

import 'package:carousel_slider/carousel_slider.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:Flutter/material.dart';

class BannerSlider extends StatefulWidget {
  @override
  _BannerSliderState createState() => _BannerSliderState();
}

class _BannerSliderState extends State<BannerSlider> {
  int _index = 0;
  int _dataLength = 1;

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

  Future getSliderImageFromDb() async {
    var _fireStore = FirebaseFirestore.instance;
    QuerySnapshot snapshot = await _fireStore.collection('Banner').get();
    if (mounted) {
      setState(() {
        _dataLength = snapshot.docs.length;
      });
    }
    return snapshot.docs;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,child: Column(
        children: [
          if (_dataLength != 0)
            FutureBuilder(
              future: getSliderImageFromDb(),builder: (_,snapShot) {
                return snapShot.data == null
                    ? Center(
                        child: CircularProgressIndicator(),)
                    : Padding(
                        padding: const EdgeInsets.only(top: 4),child: CarouselSlider.builder(
                            itemCount: snapShot.data!.length,itemBuilder: (BuildContext context,index,int) {
                              DocumentSnapshot sliderImage =
                                  snapShot.data![index];
                              Map getimage = sliderImage.data();
                              return SizedBox(
                                  width: MediaQuery.of(context).size.width,child: Image.network(
                                    getimage['image'],fit: BoxFit.fill,));
                            },options: CarouselOptions(
                                viewportFraction: 1,initialPage: 0,autoplay: true,height: 150,onPageChanged:
                                    (int i,carouselPageChangedReason) {
                                  setState(() {
                                    _index = i;
                                  });
                                })),);
              },),],);
  }
}

错误是:

  1. snapShot.data![index];
Error: The operator '[]' isn't defined for the class 'Object'.
 - 'Object' is from 'dart:core'.
Try correcting the operator to an existing operator,or defining a '[]' operator.
                                  snapShot.data![index];
                                                ^

2.snapShot.data.length,

Error: The getter 'length' isn't defined for the class 'Object'.
 - 'Object' is from 'dart:core'.
Try correcting the name to the name of an existing getter,or defining a getter or field named 'length'.
                            itemCount: snapShot.data!.length,^^^^^^

我通过添加空检查尝试了任何建议,但它不起作用。

解决方法

Firestore 的 data 曾经是 QueryDocumentSnapshot 的属性,但现在它是一个函数,data()

由于 data() 现在是一个方法/函数,您必须添加 () 括号。


错误 1 ​​-

改变这个

snapShot.data![index];

进入

snapShot.data()![index];

错误 2 -

改变这个

snapShot.data!.length

进入

snapShot.data()!.length
,

改变这个:

  Future getSliderImageFromDb() async {
    var _fireStore = FirebaseFirestore.instance;
    QuerySnapshot snapshot = await _fireStore.collection('Banner').get();
    if (mounted) {
      setState(() {
        _dataLength = snapshot.docs.length;
      });
    }
    return snapshot.docs;
  }

进入这个:

  Future<List<QueryDocumentSnapshot<Map<String,dynamic>>>> getSliderImageFromDb() async {
    var _fireStore = FirebaseFirestore.instance;
    QuerySnapshot<Map<String,dynamic>> snapshot = await _fireStore.collection('Banner').get();
    if (mounted) {
      setState(() {
        _dataLength = snapshot.docs.length;
      });
    }
    return snapshot.docs;
  }

QuerySnapshot 现在采用泛型参数,例如 Map<String,dynamic> 并且由于您返回 snapshot.docs,因此您还需要指定您返回的对象类型,例如 Future<List<QueryDocumentSnapshot<Map<String,dynamic>>>>


然后改变:

builder: (_,snapShot) {

进入这个:

builder: (_,AsyncSnapshot<List<QueryDocumentSnapshot<Map<String,dynamic>>>> snapShot) {

指定这个未来的泛型类型。在您使用的代码中,snapShot 的类型为 AsyncSnapshot<Object>,这就是您收到错误的原因:

错误:未为“Object”类定义 getter“length”。


然后也改变:

 DocumentSnapshot sliderImage = snapShot.data![index];

进入这个:

DocumentSnapshot<Map<String,dynamic>> sliderImage = snapShot.data![index];

检查:

https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/CHANGELOG.md#200

,

试试这个function

Future<dynamic> postImageFile(
    {@required File imageFile,@required String folderPath}) async {
  String fileName = DateTime.now().millisecondsSinceEpoch.toString();

  StorageReference reference =
      FirebaseStorage.instance.ref().child(folderPath).child(fileName);
  StorageUploadTask uploadTask = reference.putFile(imageFile);
  StorageTaskSnapshot storageTaskSnapshot = await uploadTask.onComplete;
  print(storageTaskSnapshot.ref.getDownloadURL());
  return storageTaskSnapshot.ref.getDownloadURL();
}

是从 firestore

获取图像的最佳方式