Flutter 2.0.2 Null 检查运算符用于空值
Flutter 2.0.2 Null check operator used on a null value
虽然我知道这可能看起来像重复,有多少不同的帖子有关于这个错误,但我收到这个错误是因为(我假设)是四个不同屏幕上的不同原因。
我的应用程序启动了,但每当我尝试导航我的应用程序时,我最终都会收到红屏错误,因为它说屏幕中的一个小部件对空值使用了 Null Check 运算符。
这是我遇到的错误:
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
这个有点不同
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
现在我假设错误出在 whatever widget 作为 WidgetName(dirty) 返回。所以每一个的代码如下。但是,除了所有这些之外,我还想问一些问题,只是为了更好地理解并帮助我在未来诊断问题。当它有 WidgetName(dirty) 时,这到底意味着什么(dity)?除了显示特定小部件的错误消息外,它还提供了“导致错误的相关小部件路径,是我应该查看的路径吗?
通知横幅:
@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,
);
}
}
}
警报横幅:
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,
);
});
}),
),
),
);
}
}
设置视图:
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;
});
}
}
到目前为止,我已经检查了我进行空检查的所有内容,但无法修复它。
我已经将 flutter 升级到 2.0.2,运行 进行了 flutter pub 缓存修复,并通过执行两次来确保这些事情正确完成。我不太确定我错过了什么,但我认为它实际上在代码中。
对我的 post 的评论帮助我确定了在哪里寻找我的问题!
这对我 运行 稍后遇到的另一个错误很有用。
由于这个问题,它最终成为 Firebase 中的某个东西,它的数据布局比我们实际使用的要旧。几乎来自 firebase 的文档之一缺少一个字段,这导致空检查运算符执行其工作并让我知道它收到了一个空值。
问题:
此错误通常发生在使用 Bang !
运算符(也称为空断言运算符)放弃可空性时。
例如:
int? i;
void main() {
print(i!.isEven); // Runtime error: Null check operator used on a null value
}
解法:
当您不确定类型是否为空时,建议使用局部变量并对其进行空检查,而不是使用 bang 运算符。
int? i;
void main() {
var local = i;
if (local != null) {
print(local.isEven);
}
}
您还可以使用 ?.
并在类型为 null
时提供默认值。
int? i;
void main() {
print(i?.isEven ?? true);
}
虽然我知道这可能看起来像重复,有多少不同的帖子有关于这个错误,但我收到这个错误是因为(我假设)是四个不同屏幕上的不同原因。
我的应用程序启动了,但每当我尝试导航我的应用程序时,我最终都会收到红屏错误,因为它说屏幕中的一个小部件对空值使用了 Null Check 运算符。
这是我遇到的错误:
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
这个有点不同
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
现在我假设错误出在 whatever widget 作为 WidgetName(dirty) 返回。所以每一个的代码如下。但是,除了所有这些之外,我还想问一些问题,只是为了更好地理解并帮助我在未来诊断问题。当它有 WidgetName(dirty) 时,这到底意味着什么(dity)?除了显示特定小部件的错误消息外,它还提供了“导致错误的相关小部件路径,是我应该查看的路径吗?
通知横幅:
@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,
);
}
}
}
警报横幅:
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,
);
});
}),
),
),
);
}
}
设置视图:
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;
});
}
}
到目前为止,我已经检查了我进行空检查的所有内容,但无法修复它。 我已经将 flutter 升级到 2.0.2,运行 进行了 flutter pub 缓存修复,并通过执行两次来确保这些事情正确完成。我不太确定我错过了什么,但我认为它实际上在代码中。
对我的 post 的评论帮助我确定了在哪里寻找我的问题!
这对我 运行 稍后遇到的另一个错误很有用。
由于这个问题,它最终成为 Firebase 中的某个东西,它的数据布局比我们实际使用的要旧。几乎来自 firebase 的文档之一缺少一个字段,这导致空检查运算符执行其工作并让我知道它收到了一个空值。
问题:
此错误通常发生在使用 Bang !
运算符(也称为空断言运算符)放弃可空性时。
例如:
int? i;
void main() {
print(i!.isEven); // Runtime error: Null check operator used on a null value
}
解法:
当您不确定类型是否为空时,建议使用局部变量并对其进行空检查,而不是使用 bang 运算符。
int? i; void main() { var local = i; if (local != null) { print(local.isEven); } }
您还可以使用
?.
并在类型为null
时提供默认值。int? i; void main() { print(i?.isEven ?? true); }