Home > database >  Error Null check operator used on a null value Flutter
Error Null check operator used on a null value Flutter

Time:01-11

I get this error in the StreamBuilder: enter image description here

Here's the code:

import 'dart:async';

import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';

class NewCauseMenu extends StatefulWidget {
  String? area;
  NewCauseMenu(this.area, {super.key});

  @override
  State<NewCauseMenu> createState() => _NewCauseMenuState();
}

class _NewCauseMenuState extends State<NewCauseMenu> {
  final db = FirebaseDatabase.instance;

  String? dropdownValue;
  String? problem;
  String? causa1;
  String? causa2;
  String? causa3;
  String? causa4;

  var setDefaultProblem = true, setDefaultCauseOne = true;
  @override
  Widget build(BuildContext context) {
    final myRef = db.ref();

    return WillPopScope(
      onWillPop: () {
        return _onWillPopScope();
      },
      child: SafeArea(
          child: Scaffold(
        appBar: AppBar(
          title: Text('Menú Nueva Causa ${widget.area}'),
        ),
        body: Center(
          child: Column(
            children: [
              const SizedBox(
                height: 25,
              ),
              StreamBuilder(
                  stream: myRef.child(widget.area.toString()).onValue,
                  builder: (context, snapshot) {
                    if (!snapshot.hasData) return Container();
                    final data = Map<String, dynamic>.from(
                        (snapshot.data)!.snapshot.value as Map);
                    if (setDefaultProblem) {
                      problem = data.keys.first.toString();
                    }
                    return DropdownButton(
                      value: problem,
                      icon: const Icon(Icons.arrow_downward),
                      isExpanded: false,
                      elevation: 16,
                      underline: Container(
                        height: 2,
                        color: Colors.blueAccent,
                      ),
                      items: data.keys.map(((e) {
                        return DropdownMenuItem(
                            value: e.toString(), child: Text(e.toString()));
                      })).toList(),
                      onChanged: (value) {
                        setState(() {
                          problem = value!;
                          setDefaultProblem = false;
                          setDefaultCauseOne = true;
                        });
                      },
                    );
                  }),
              const SizedBox(
                height: 25,
              ),
              problem != null
                  ? StreamBuilder(
                      stream: myRef
                          .child(widget.area.toString())
                          .child(problem.toString())
                          .onValue,
                      builder: (context, snapshot) {
                        final data = Map<String, dynamic>.from(
                            (snapshot.data!.snapshot.value as Map));
                        if (!snapshot.hasData) {
                          debugPrint('snapshot status: ${snapshot.error}');
                          return Text(
                              'snapshot empty problem: $problem causa #1: $causa1');
                        }

                        debugPrint(data.toString());
                        if (setDefaultCauseOne) {
                          causa1 = data.keys.first.toString();
                        }
                        return DropdownButton(
                          value: causa1,
                          icon: const Icon(Icons.arrow_downward),
                          isExpanded: false,
                          elevation: 16,
                          underline: Container(
                            height: 2,
                            color: Colors.blueAccent,
                          ),
                          items: data.keys.map(((e) {
                            return DropdownMenuItem(
                                value: e.toString(), child: Text(e.toString()));
                          })).toList(),
                          onChanged: (value) {
                            setState(() {
                              causa1 = value!;
                              setDefaultCauseOne = false;
                            });
                          },
                        );
                      },
                    )
                  : Text('problem null problem: $problem causa #1: $causa1')
            ],
          ),
        ),
      )),
    );
  }

  Future<bool> _onWillPopScope() async {
    Navigator.of(context).pop();
    return false;
  }
}

I don't know why in the second StreamBuilder there's a Null value in the snapshot.data. I defined the var problem in the first StreamBuilder and it should work with the second one. But it doesn't.

When I run the program, happens this:

enter image description here

After the error, it seems that the app works perfectly.

I verified that the var problem must get a value, otherwise the second StreamBuilder doesn't work. I give a value for the var getting the first key of the snapshot.data but for some reason in the beginning there's no value. That's the root of the problem. Help me, please. I don't know what to do.

CodePudding user response:

The "null pointer" exception is thrown when you try to access a property or call a method on an object that is null. In your code, it looks like this happens on the line final data = Map<String, dynamic>.from((snapshot.data!.snapshot.value as Map)); where you try to access the "data" attribute of the "snapshot".

Here's the problem: In a Firebase stream, if no data is received, then snapshot.data will be null. So if there is no data, you should not try to access snapshot.data. You can get around this by adding an if (snapshot.data != null) check before trying to access snapshot.data.

So your code should look like this in the second StreamBuilder:

if (!snapshot.hasData) {
   debugPrint('snapshot status: ${snapshot.error}');
   return Text('snapshot empty problem: $problem causa #1: $causa1');
}
final data = Map<String, dynamic>.from((snapshot.data!.snapshot.value as Map));

CodePudding user response:

just change the position and add new condition same as below

if (!snapshot.hasData || snapshot.data == null) {
                          debugPrint('snapshot status: ${snapshot.error}');
                          return Text(
                              'snapshot empty problem: $problem causa #1: $causa1');
                        }
final data = Map<String, dynamic>.from(
                            (snapshot.data!.snapshot.value as Map));

                        debugPrint(data.toString());
                        if (setDefaultCauseOne) {
                          causa1 = data.keys.first.toString();
                        }
  • Related