25

I'm new to Flutter. I am trying to develop an application.

I want to show the staff list in the Firebase database. However, I am getting the following error.

Error :

The method '[]' can't be unconditionally invoked because the receiver can be 'null'. Try making the call conditional (using '?.') or adding a null check to the target ('!').

Kodlarım :

`import 'package:calendar/page/mainPage.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class Staff extends StatefulWidget {
  @override
  _StaffState createState() => _StaffState();
}

class _StaffState extends State<Staff> {
  
  final _firestore = FirebaseFirestore.instance;

  @override
  Widget build(BuildContext context) {
    // ignore: unused_local_variable
    CollectionReference staffRef = _firestore.collection('staff');

    return Scaffold(
      appBar: AppBar(
        title: Text("Personel Listesi"),
        backgroundColor: Colors.redAccent[400],
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.home),
            onPressed: () {
              Navigator.pushAndRemoveUntil(
                  context,
                  MaterialPageRoute(builder: (_) => MainPage()),
                  (route) => true);
            },
          ),
        ],
      ),
      body: Container(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Center(
            child: Column(
              children: [
                StreamBuilder<QuerySnapshot>(
                  stream: staffRef.snapshots(),
                  builder: (BuildContext context, AsyncSnapshot asyncSnapshot) {
                    if (asyncSnapshot.hasError) {
                      return Center(
                          child: Text(
                              "Bir hata oluştu, lütfen tekrar deneyiniz."));
                    } else {
                      if (asyncSnapshot.hasData) {
                        List<DocumentSnapshot> listStaff =
                            asyncSnapshot.data.docs;
                        return Flexible(
                          child: ListView.builder(
                              itemBuilder: (context, index) {
                                return Card(
                                  elevation: 20,
                                  color: Colors.greenAccent[200],
                                  child: ListTile(
                                    trailing: IconButton(
                                      icon: Icon(Icons.delete),
                                      onPressed: () async {
                                        await listStaff[index]
                                            .reference
                                            .delete();
                                      },
                                    ),
                                    title: Text(
                                      '${listStaff[index].data['nameSurname']}',
                                      style: TextStyle(fontSize: 20),
                                    ),
                                    subtitle: Column(
                                      children: [
                                        Row(
                                          mainAxisAlignment:
                                              MainAxisAlignment.start,
                                          children: [
                                            Text(
                                              '${listStaff[index].data['tip']}',
                                              style: TextStyle(fontSize: 14),
                                            ),
                                          ],
                                        ),
                                        Row(
                                          mainAxisAlignment:
                                              MainAxisAlignment.start,
                                          children: [
                                            Text(
                                              '${listStaff[index].data['mail']}',
                                              style: TextStyle(fontSize: 14),
                                            ),
                                          ],
                                        ),
                                        Row(
                                          mainAxisAlignment:
                                              MainAxisAlignment.start,
                                          children: [
                                            Text(
                                              '${listStaff[index].data['phone']}',
                                              style: TextStyle(fontSize: 14),
                                            ),
                                          ],
                                        ),
                                      ],
                                    ),
                                  ),
                                );
                              },
                              itemCount: listStaff.length),
                        );
                      } else {
                        return Center(
                          child: CircularProgressIndicator(),
                        );
                      }
                    }
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
`
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440

4 Answers4

19

In the new flutter update, we don't need to add .data()

my codes below

title: Text(
                                  **'${listStaff[index].data['nameSurname']}',**
                                  style: TextStyle(fontSize: 20),
                                ),

Changing it like this fixed the error.

title: Text(
                                  **'${listPersonel[index]['nameSurname']}'**,
                                  style: TextStyle(fontSize: 20),
                                ),
16

Problem:

You get this error if you're accessing an element on a nullable List or Map. Let's understand it for a List and you can apply the same solutions for your Map.

For example:

List<int>? someList;

void main() {
  int a = someList[0]; // Error
}

Solutions:

  • Use a local variable:

    var list = someList;
    if (list != null) {
      int a = list[0]; // No error
    }
    
  • Use ? and ??:

    int a = someList?[0] ?? -1; // -1 is the default value if List was null
    
  • Use ! bang operator only if you're sure that the List isn't null.

    int a = someList![0];
    

For those who are using FutureBuilder/StreamBuilder:

You can solve the error in two ways:

  • Specify a type to your FutureBuilder/StreamBuilder

    FutureBuilder<List<int>>( // <-- type 'List<int>' is specified.
      future: _listOfInt(),
      builder: (_, snapshot) {
        if (snapshot.hasData) {
          List<int> myList = snapshot.data!; // <-- Your data
        }
        return Container();
      },
    )
    
  • Use as to downcast Object to your type, say a List or Map.

    FutureBuilder(
      future: _listOfInt(),
      builder: (_, snapshot) {
        if (snapshot.hasData) {
          var myList = snapshot.data! as List<int>; // <-- Your data using 'as'
        }
        return Container();
      },
    )
    
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
4

I was having the same problem as the questioner and the solution came from this post. I leave it here in case anyone else has this problem. https://fileidea.com/2021/05/05/method-cant-be-unconditionally-invoked-because-the-receiver-can-be-null-with-firestore/

before:

 final mySnapStream = messagesCollection
.orderBy('date', descending: true)
.limit(100)
.snapshots()
.map((obj) => obj.docs
    .map((e) => new MyItem(
        e.data()['myFieldOne'],
        e.data()['myFieldThree'],
        e.data()['myFieldFour']))
    .toList());

after:

    final mySnapStream = messagesCollection
  .orderBy('date', descending: true)
  .limit(100)
  .snapshots()
  .map((obj) => obj.docs
      .map((e) => new MyItem(
          (e.data() as dynamic)['myFieldOne'],
          (e.data() as dynamic)['myFieldThree'],
          (e.data() as dynamic)['myFieldFour']))
      .toList());
2

It is a typical null-safety related error. I did not try the code, by I guess that probably assigning asyncSnapshot.data.docs to listStaff possibly may return null, but your declared type List<DocumentSnapshot> doesn't allow for that. If you are 100% sure that this assignment won't return null value, you can add '!' to ensure compiler, that it will be List, so it will let you use methods. Although if you want this list to be nullabe, you can simply add '?' to show it, and than use '?.' to use methods. It works like: Check if the object is null and execute method on this method only if its not.

Wiktor
  • 726
  • 5
  • 20