'Fetching image from Firebase FireStore into carousel Flutter

Hi everyone I am referring on YouTube video on displaying images in carousel from firestore in flutter mobile app. However there are some problems that i couldnt solve. Hope anyone can kindly help me for my school project. Thanks!

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

The errors are:

  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,
                                                      ^^^^^^

I have try any suggestion by adding null check but it doesn't work.



Solution 1:[1]

Firestore's data used to be a property of QueryDocumentSnapshot, but now it is a function, data().

Since data() is a method/function now, you have to add () parenthesis.


Error 1 -

Change this

snapShot.data![index];

into

snapShot.data()![index];

Error 2 -

Change this

snapShot.data!.length

into

snapShot.data()!.length

Solution 2:[2]

Change this:

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

into this:

  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 now takes a generic parameter for example Map<String,dynamic> and since you are return snapshot.docs then you also need to specify the type of object you are returning for example Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>>


Then change:

builder: (_, snapShot) {

into this:

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

specifying the generic type of this future. In the code you are using the snapShot is of type AsyncSnapshot<Object> and that's why you get the error:

Error: The getter 'length' isn't defined for the class 'Object'.


Then also change:

 DocumentSnapshot sliderImage = snapShot.data![index];

into this:

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

check:

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

Solution 3:[3]

try this 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();
}

is the best way to get images from firestore

Solution 4:[4]

Error: Cannot run with sound null safety, because the following dependencies don't support null safety:

  • package:carousel_slider

For solutions, see https://dart.dev/go/unsound-null-safety

I have solved all the errors and now getting the error with package:carousel_slider ^2.3.1 I have used the latest, but it's ignoring all the code. If someone knows about this, please contribute

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Peter Haddad
Solution 3 Ala'a Lahlouh
Solution 4 Mayur Dokras