While I know this may look like a duplicate with how many different posts there are about this error but I am getting this error for (which I assume) are different reasons on four different screens.
My app launches but I end up getting the Red screen error whenever I try to navigate my app because it says a widget within the screen used a Null Check operator on a null value.
Here are the errors I've gotten:
The following _CastError was thrown building NotificationBanner(dirty): Null check operator used on a null value. The relevant error-causing widget was: NotificationBanner file:///Users/alexm/carebloom-flutter/lib/Views/homeview.dart:9:7
The following _CastError was thrown building AlertBanner(dirty): Null check operator used on a null value. The relevant error-causing widget was: AlertBanner file:///Users/alexm/carebloom-flutter/lib/Views/alerts_view.dart:57:15
The following _CastError was thrown building MessageOverView(dirty): Null check operator used on a null value. The relevant error-causing widget was: MessageOverView file:///Users/alexm/carebloom-flutter/lib/widgets/navbar.dart:41:16
This one is a little different
The following _CastError was thrown building SettingsView(dirty, dependencies: [_EffectiveTickerMode], state: _SettingsViewState#ddb1e(tickers: tracking 1 ticker)): Null check operator used on a null value. The relevant error-causing widget was: SettingsView file:///Users/alexm/carebloom-flutter/lib/widgets/navbar.dart:49:16
Now I assume that the errors lie within the whatever widget came back as WidgetName(dirty). SO the code for each of those is below. However I'd like to also ask some questions on top of all this just to better my understanding and help me diagnose issues in the future. When it has WidgetName(dirty) what exactly does that mean what is (dity)? Besides the error message showing a specific widget it also gives 'The relevant error-causing widget path, is that the one I should be looking at?
NotificationBanner:
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('alerts')
.where('access',
arrayContains: FirebaseAuth.instance.currentUser!.uid)
.where('read', isEqualTo: false)
//.orderBy('createdAt', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData || snapshot.data!.docs.length <= 0) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
height: 60.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 10.0),
Icon(
Icons.check_box,
color: Colors.green,
size: MediaQuery.of(context).size.width * .1,
),
SizedBox(width: 5.0),
Expanded(
child: AutoSizeText(
"No Current Messages or Alerts",
maxLines: 1,
maxFontSize: 20,
style:
TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
//if (snapshot.hasData) SizedBox(width: 45),
],
),
);
}
Alert alert = Alert.fromFirestore(snapshot.data!.docs.first);
return Card(
//height: 60.0,
child: InkWell(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 10.0),
Icon(
Icons.warning,
color: Colors.red,
size: MediaQuery.of(context).size.width * .1,
),
SizedBox(width: 15.0),
Expanded(
child: AutoSizeText(
"New Alert for Your Patient",
maxLines: 1,
maxFontSize: 20,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
),
),
//if (snapshot.hasData) SizedBox(width: 45),
if (snapshot.hasData) Icon(Icons.arrow_right, size: 50)
],
),
onTap: () {}),
elevation: 12,
);
});
}
Widget getIcon(snapshot) {
if (snapshot.hasData) {
return Icon(
Icons.warning,
color: Colors.red,
size: 60,
);
} else {
return Icon(
Icons.check_box,
color: Colors.green,
size: 60,
);
}
}
}
AlertBanner:
import 'package:carebloom/models/alert_model.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class AlertBanner extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('alerts')
.where('access',
arrayContains: FirebaseAuth.instance.currentUser!.uid)
.where('read', isEqualTo: false)
.orderBy('createdAt', descending: true)
.snapshots(),
builder: (context, snapshot) {
print(snapshot.hasData);
print('alert has error');
print(snapshot.hasError);
if (snapshot.hasError) {
print(snapshot.error);
}
if (!snapshot.hasData || snapshot.data!.docs.length <= 0) {
return Card(
child: SizedBox(
height: MediaQuery.of(context).size.height * .08,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 10.0),
Icon(
Icons.check_box,
color: Colors.green,
size: MediaQuery.of(context).size.width * .1,
),
SizedBox(width: 5.0),
Expanded(
child: AutoSizeText(
"No Current Messages or Alerts",
maxLines: 1,
maxFontSize: 20,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
),
),
//if (snapshot.hasData) SizedBox(width: 45),
],
),
),
);
}
Alert curAlert = Alert.fromFirestore(snapshot.data!.docs.elementAt(0));
return Card(
child: SizedBox(
height: MediaQuery.of(context).size.height * .08,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 10.0),
Icon(
Icons.warning_rounded,
color: Colors.red,
size: MediaQuery.of(context).size.width * .1,
),
SizedBox(width: MediaQuery.of(context).size.width * .08),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AutoSizeText(
curAlert.desc!.toLowerCase().capitalizeFirstofEach,
maxLines: 1,
maxFontSize: 20,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold)),
AutoSizeText(
curAlert.fname + ' ' + '${curAlert.lname[0]}' + '.',
maxLines: 1,
maxFontSize: 20,
style: TextStyle(
fontSize: 18,
),
),
],
),
Spacer(), //SizedBox(width: MediaQuery.of(context).size.width * .1),
Icon(Icons.arrow_right, size: 50)
//if (snapshot.hasData) SizedBox(width: 45),
],
),
),
);
});
}
}
extension StringFormatExtension on String {
String get capitalizeFirstofEach => this
.split(" ")
.map((str) => str[0].toUpperCase() + str.substring(1))
.join(" ");
}
MessageOverView:
import 'package:auto_size_text/auto_size_text.dart';
import 'package:carebloom/Services/auth.dart';
import 'package:carebloom/models/last_message_model.dart';
import 'package:carebloom/models/converstaions.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
class MessageOverView extends StatelessWidget {
// This widget is the root of your application.
final AuthService _auth = AuthService();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
backgroundColor: Color(0xFF6cc5de),
title: AutoSizeText(
'Messages',
maxLines: 1,
style: GoogleFonts.raleway(
fontWeight: FontWeight.bold,
fontSize: 35,
textStyle: TextStyle(
color: Colors.black,
)),
textAlign: TextAlign.center,
),
),
body: Container(
padding: EdgeInsets.all(2.5),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomCenter,
colors: [Color(0xFFb5e2ee), Colors.white])),
child: Container(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('messages')
.where('access',
arrayContains: FirebaseAuth.instance.currentUser!.uid)
//FirebaseAuth.instance.currentUser.uid, isEqualTo: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container();
}
print("after message list query*****************************");
print(snapshot.data!.docs.toString());
print(snapshot.data!.docs.length);
return ListView.builder(
itemCount: 1,
itemBuilder: (context, pos) {
LastMessage msg = LastMessage.fromFirestore(
snapshot.data!.docs.elementAt(pos));
print('error before or after??????/');
print(snapshot.data!.docs.contains(msg.id));
return ConversationList(
patient: msg.fname! + ' ' + msg.lname!,
name: msg.author,
messageText: msg.text,
imageUrl: msg.photoURL,
time: DateFormat('MMM d, h:mma')
.format(msg.msgRecieved!.toDate()),
isMessageRead: false,
pos: pos,
id: msg.id,
);
});
}),
),
),
);
}
}
SettingsView:
import 'dart:io';
import 'package:carebloom/Screens/login.dart';
import 'package:carebloom/Services/auth.dart';
import 'package:carebloom/Services/image_picker_handler.dart';
import 'package:carebloom/models/user.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class SettingsView extends StatefulWidget {
SettingsView({Key? key}) : super(key: key);
@override
_SettingsViewState createState() => _SettingsViewState();
}
class _SettingsViewState extends State<SettingsView>
with TickerProviderStateMixin, ImagePickerListener {
// This widget is the root of your application.
final AuthService _auth = AuthService();
File? _image;
AnimationController? _controller;
late ImagePickerHandler imagePicker;
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 500),
);
imagePicker = new ImagePickerHandler(this, _controller);
imagePicker.init();
}
@override
void dispose() {
_controller!.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
print('Before query settings');
return Stack(children: [
StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.get()
.asStream(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container();
}
LUser user = LUser.fromFirestore(snapshot.data!);
return Column(
children: [
Container(
width: double.infinity,
child: Center(
child: CircleAvatar(
backgroundColor: Colors.white,
//backgroundImage: NetworkImage(user.photo),
foregroundColor: Colors.grey[600],
child: null == user.photo
? CircleAvatar(
child: Icon(
Icons.person,
size: 210,
color: Colors.grey[600],
),
backgroundColor: Colors.white,
radius: 110,
)
: CircleAvatar(
backgroundImage: NetworkImage(user.photo!),
backgroundColor: Colors.white,
radius: 110,
),
radius: 110,
),
),
),
ElevatedButton(
onPressed: () => imagePicker.showDialog(context),
child: Icon(Icons.camera_alt_outlined),
style: ElevatedButton.styleFrom(
primary: Color(0xFF3E8094),
onPrimary: Colors.white,
shadowColor: Color(0xFF6cc5de),
elevation: 5,
padding: EdgeInsets.fromLTRB(5, 5, 5, 5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
side: BorderSide(color: Color(0xFF6CC5DE))),
),
),
Container(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 20,
),
Text(
'Name: ' + user.fname! + ' ' + user.lname!,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 20,
),
Text(
'Email: ' + user.email!,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 20,
),
],
),
),
Container(
width: double.infinity,
height: 50,
child: ElevatedButton(
child: Text('Sign Out'),
style: ElevatedButton.styleFrom(
primary: Color(0xFF3E8094),
onPrimary: Colors.white,
shadowColor: Color(0xFF6cc5de),
elevation: 5,
padding: EdgeInsets.fromLTRB(5, 5, 5, 5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
side: BorderSide(color: Color(0xFF6CC5DE))),
),
onPressed: () async {
await _auth.signOut();
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => LoginScreen(),
fullscreenDialog: true));
}
// }
),
),
],
);
}),
]);
}
@override
userImage(File? _image) {
setState(() {
this._image = _image;
});
}
}
I've checked everything that I have a null check on so far and haven't been able to fix it. I've upgraded flutter to 2.0.2, ran a flutter pub cache repair, and ensured that those things were done properly by doing them twice. I'm not exactly sure what I'm missing but I'm thinking its actually in the code.