Sin Lee
Sin Lee

Reputation: 135

Android Flutter how to show data searched in ListView? Error: The operator '[]' isn't defined for the class 'Object'

I am new to Flutter as well as Android, currently I am doing Search Data from Firestore. I was able to get the data but I couldn't display it on the screen. I'm getting this error

"The method '[]' can't be unconditionally invoked because the receiver can be 'null'."

_querySnapshot.docs[index].data()['name']

And this is the code I'm using for searching

 late QuerySnapshot _querySnapshot;

@override
          Widget build(BuildContext context) {
            Widget searchedData() {
              return ListView.builder(
                  itemCount: _querySnapshot.docs.length,
                  itemBuilder: (BuildContext context, int index) {
                    return ListTile(
                      title: Text(
                        _querySnapshot.docs[index].data()['name'],
                        //
                      ),
                    );
                  });
            }
    
        return LayOut(
          Scaffold(
            floatingActionButton: FloatingActionButton(
                child: Icon(Icons.clear), onPressed: emptyTextSearch),
            appBar: AppBar(
              actions: [
                GetBuilder<DataController>(
                    init: DataController(),
                    builder: (val) {
                      return IconButton(
                          icon: Icon(Icons.search),
                          onPressed: () {
                            val.queryData(_searchController.text).then((value) {
                              _querySnapshot = value;
                              setState(() {
                                isExcecuted = true;
                              });
                            });
                          });
                    })
              ],
              title: TextField(
                style: TextStyle(color: Colors.white),
                decoration: InputDecoration(
                    hintText: 'Search', hintStyle: TextStyle(color: Colors.white)),
                controller: _searchController,
              ),
              backgroundColor: Colors.black,
            ),
            body: isExcecuted
                ? searchedData()
                : Container(
                    child: Center(
                      child: Text(
                        'Search any',
                        style: TextStyle(color: Colors.white, fontSize: 30.0),
                      ),
                    ),
                  ),
          ),
        );
       }

DataController

     class DataController extends GetxController {
      Future getData(String collection) async {
        final FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
        QuerySnapshot snapshot =
            await firebaseFirestore.collection(collection).get();
        return snapshot.docs;
      }
    
      Future queryData(String queryString) async {
        return FirebaseFirestore.instance
            .collection('reports')
            .where('property', isGreaterThanOrEqualTo: queryString)
            .get();
      }
    }

Please help me get past this error.

Upvotes: 1

Views: 91

Answers (2)

Peter Obiechina
Peter Obiechina

Reputation: 2835

@Frank's answer should work.

But you can also try this:

Map<String, dynamic> searchData = _querySnapshot.docs[index].data();
return ListTile(
  title: Text(
    searchData['name'],
  ),
);

or

List<Map<String, dynamic>> searchData = _querySnapshot.docs
.map((e) => e.data()).toList();
print(searchData);
return ListView.builder(
  itemCount: searchData.length,
  itemBuilder: (BuildContext context, int index) {
    return ListTile(
      title: Text(
        searchData[index]['name'],
      ),
    );
});

Also, update your code to use stricter types:

late QuerySnapshot<Map<String, dynamic>> _querySnapshot;
...
Future<QuerySnapshot<Map<String, dynamic>>> queryData(String queryString) async {
  return await FirebaseFirestore.instance
    .collection('reports')
    .where('property', isGreaterThanOrEqualTo: queryString)
    .get();
}

Upvotes: 1

Frank van Puffelen
Frank van Puffelen

Reputation: 599876

You're using version 2.0 (or later) of the FlutterFire plugin for Firestore, which requires that you specify the type of a query/snapshot. According to the documentation on migrating to cloud_firestore 2.0.

The shortest I can think of is:

(_querySnapshot.docs[index].data() as Map<String, dynamic>)['name']

But if that doesn't work you might need to modify the type of the val.queryData that you use her:

val.queryData(_searchController.text).then((value) {

Your queryData returns a Query now and that needs to be a Query<Map<String, dynamic>>. By changing that the value in then becomes a DocumentSnapshot<Map<String, dynamic>>, so that finally (_querySnapshot.docs[index].data() becomes a Map<String, dynamic>, which is what you need.

Upvotes: 2

Related Questions