I'm writing a code where an Admin is uploading images to firebase. The error comes when I put an if else statement to two functions first function allows you to capture images at Admin's home screen from camera and gallery and the second function takes that image where you can write descriptions of that product in the image. But after capturing image from mobile camera or gallery the error shows up of null check value with red screen. I think it's due to bang operator but I'm finding difficulty to make an alternate statement to run two functions in if(?) else(:) statement.
Below Error Show after Implementing the following if else statement
When I click one of on an error line in Console it takes me to the following position
FLUTTER DOCTOR
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.2.3, on Microsoft Windows [Version 10.0.19041.1165], locale en-PK)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Android Studio
[√] Connected device (3 available)
• No issues found!
Below is the function where the error line points out to a bang(!) operator
pickPhotoFromGallery()async {
final imagefile= await ImagePicker().pickImage(source: ImageSource.gallery);
final _imageselected=File(imagefile!.path);
setState(() {
this.file=_imageselected;
});
}
displayAdminiUploadFormScreen(){
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
),
leading: IconButton(icon: Icon(Icons.arrow_back,color: Colors.white,),
onPressed: clearFormInfo(),
),
title: Text('New Product',style: TextStyle(color: Colors.white,fontSize: 24.0,fontWeight: FontWeight.bold),),
actions: [
FlatButton(onPressed: (){
uploading ? null: uploadImageandSaveItem();
},
child: Text('Add',style: TextStyle(color: Colors.pink,fontSize: 16.0,fontWeight: FontWeight.bold),)
),
],
),
body: ListView(
children: [
uploading ? circularProgress():Text(''),
Container(
height: 230.0,
width: MediaQuery.of(context).size.width*0.8,
child: Center(
child: AspectRatio
(aspectRatio: 16/9,
child: Container(
decoration: BoxDecoration(image:DecorationImage(image:FileImage(file!),fit:BoxFit.cover)),
),
),
),
),
Padding(padding: EdgeInsets.only(top: 12.0)),
UplaodItems.dart(Compelet Code Dart File in case if someone requires it as well, here person is selecting , writing descriptions on a form and uploading images)
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:ecom_app/Widgets/loadingwidget.dart';
import 'package:ecom_app/main.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'adminShiftOrders.dart';
class UploadPage extends StatefulWidget {
const UploadPage({Key? key}) : super(key: key);
@override
_UploadPageState createState() => _UploadPageState();
}
class _UploadPageState extends State<UploadPage> {
bool get wantKeepAlive =>true;
File? file;
TextEditingController _descriptionTEC=TextEditingController();
TextEditingController _priceTEC=TextEditingController();
TextEditingController _titleTEC=TextEditingController();
TextEditingController _shortInfoTEC=TextEditingController();
String productId=DateTime.now().microsecondsSinceEpoch.toString();
bool uploading=true;
@override
Widget build(BuildContext context) {
return file == null ? displayAdminHomeScreen() : displayAdminiUploadFormScreen();
}
displayAdminHomeScreen(){
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
),
leading: IconButton(
onPressed: (){
Route route=MaterialPageRoute(builder: (c)=> AdminShiftOrders());
Navigator.pushReplacement(context, route);
},
icon: Icon(Icons.border_color,color: Colors.white,),
),
actions: [
FlatButton(
onPressed: (){
Route route=MaterialPageRoute(builder: (c)=> SplashScreen());
Navigator.pushReplacement(context, route);
},
child: Text('Logout',style: TextStyle(color: Colors.pink,fontSize: 16.0,
fontWeight: FontWeight.bold)))
],
),
body: getAdminHomeScreenBody(),
);
}
getAdminHomeScreenBody(){
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
child: Center(
child: Column
(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.shop_2,color: Colors.white,size: 200,),
Padding(
padding: EdgeInsets.only(top: 20.0),
child: RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(9.0)),
child: Text('Add New Items',style: TextStyle(color: Colors.white,fontSize: 20.0),),
color: Colors.green,
onPressed: (){
takeImage(context);
},
),
)
],
),)
);
}
takeImage(mcontex){
return showDialog(
context: mcontex,
builder: (con)
{
return SimpleDialog(
title: Text('Item Image',style: TextStyle(color: Colors.green,fontWeight: FontWeight.bold)),
children: [
SimpleDialogOption(
child: Text('Capture Imge With Camera',style: TextStyle(color: Colors.green),),
onPressed: (){
capturePhotoWithCamer();
},
),
SimpleDialogOption(
child: Text('Select Image from Gallery',style: TextStyle(color: Colors.green),),
onPressed: (){
pickPhotoFromGallery();
},
),
SimpleDialogOption(
child: Text('Cancel',style: TextStyle(color: Colors.green),),
onPressed: (){
Navigator.pop(context);
},
)
],
);
}
);
}
capturePhotoWithCamer() async{
final imagefile= await ImagePicker().pickImage(source:ImageSource.camera,maxHeight: 680.0,maxWidth: 970.0);
final _imagefile=File(imagefile!.path);
setState(() {
this.file=_imagefile;
});
}
pickPhotoFromGallery()async {
final imagefile= await ImagePicker().pickImage(source: ImageSource.gallery);
final _imageselected=File(imagefile!.path);
setState(() {
this.file=_imageselected;
});
}
displayAdminiUploadFormScreen(){
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
),
leading: IconButton(icon: Icon(Icons.arrow_back,color: Colors.white,),
onPressed: clearFormInfo(),
),
title: Text('New Product',style: TextStyle(color: Colors.white,fontSize: 24.0,fontWeight: FontWeight.bold),),
actions: [
FlatButton(onPressed: (){
uploading ? null: uploadImageandSaveItem();
},
child: Text('Add',style: TextStyle(color: Colors.pink,fontSize: 16.0,fontWeight: FontWeight.bold),)
),
],
),
body: ListView(
children: [
uploading ? circularProgress():Text(''),
Container(
height: 230.0,
width: MediaQuery.of(context).size.width*0.8,
child: Center(
child: AspectRatio
(aspectRatio: 16/9,
child: Container(
decoration: BoxDecoration(image:DecorationImage(image:FileImage(file!),fit:BoxFit.cover)),
),
),
),
),
Padding(padding: EdgeInsets.only(top: 12.0)),
ListTile(
leading: Icon(Icons.perm_device_information,color: Colors.pink,),
title: Container(
width: 250.0,
child: TextField(
style: TextStyle(
color: Colors.deepOrangeAccent,
),
controller: _titleTEC,
decoration: InputDecoration(
hintText: 'Title',
hintStyle: TextStyle(color: Colors.deepOrange),
border: InputBorder.none
),
),
),
),
Divider(
color: Colors.deepOrangeAccent,
),
ListTile(
leading: Icon(Icons.perm_device_information,color: Colors.pink,),
title: Container(
width: 250.0,
child: TextField(
style: TextStyle(
color: Colors.deepOrangeAccent,
),
controller: _shortInfoTEC,
decoration: InputDecoration(
hintText: 'Short Info',
hintStyle: TextStyle(color: Colors.deepOrange),
border: InputBorder.none
),
),
),
),
Divider(
color: Colors.deepOrangeAccent,
),
ListTile(
leading: Icon(Icons.perm_device_information,color: Colors.pink,),
title: Container(
width: 250.0,
child: TextField(
style: TextStyle(
color: Colors.deepOrangeAccent,
),
controller: _descriptionTEC,
decoration: InputDecoration(
hintText: 'Description',
hintStyle: TextStyle(color: Colors.deepOrange),
border: InputBorder.none
),
),
),
),
Divider(
color: Colors.deepOrangeAccent,
),
ListTile(
leading: Icon(Icons.perm_device_information,color: Colors.pink,),
title: Container(
width: 250.0,
child: TextField(
keyboardType: TextInputType.number,
style: TextStyle(
color: Colors.deepOrangeAccent,
),
controller: _priceTEC,
decoration: InputDecoration(
hintText: 'Price',
hintStyle: TextStyle(color: Colors.deepOrange),
border: InputBorder.none
),
),
),
),
Divider(
color: Colors.deepOrangeAccent,
),
],
),
);
}
clearFormInfo(){
setState(() {
file=null;
_descriptionTEC.clear();
_priceTEC.clear();
_shortInfoTEC.clear();
_titleTEC.clear();
});
}
uploadImageandSaveItem()async{
setState(() {
uploading=true;
});
String imagedownloadUrl =await uploadItemImage(file);
saveItemInfo(imagedownloadUrl);
}
uploadItemImage(mfileimage)async{
final Reference reference=FirebaseStorage.instance.ref().child('items');
UploadTask uploadTask=reference.child('prodcut_$productId.jpg').putFile(mfileimage);
TaskSnapshot snapshot=await uploadTask.whenComplete(() => null);
String downloadUrl=await snapshot.ref.getDownloadURL();
return downloadUrl;
}
saveItemInfo(String downloadUrl){
final itemRef=FirebaseFirestore.instance.collection('items');
itemRef.doc(productId).set({
'shortInfo':_shortInfoTEC.text.trim(),
'longDescription':_descriptionTEC.text.trim(),
'price':_priceTEC.text.trim(),
'publishedDate':DateTime.now(),
'status':'available',
'thumbnailUrl': downloadUrl,
'title':_titleTEC.text.trim(),
});
setState(() {
file=null;
uploading=false;
productId=DateTime.now().millisecondsSinceEpoch.toString();
_descriptionTEC.clear();
_titleTEC.clear();
_shortInfoTEC.clear();
_priceTEC.clear();
});
}
}
UPDATED
item.dart(Here the data, which has to be uploaded to firestore are made in json)
import 'package:cloud_firestore/cloud_firestore.dart';
class ItemModel {
String? title;
String? shortInfo;
Timestamp? publishedDate;
String? thumbnailUrl;
String? longDescription;
String? status;
int? price;
ItemModel(
{required this.title,
required this.shortInfo,
required this.publishedDate,
required this.thumbnailUrl,
required this.longDescription,
required this.status,
required this.price,
});
ItemModel.fromJson(Map<String, dynamic> json) {
title = json['title'];
shortInfo = json['shortInfo'];
publishedDate = json['publishedDate'];
thumbnailUrl = json['thumbnailUrl'];
longDescription = json['longDescription'];
status = json['status'];
price = json['price'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['title'] = this.title;
data['shortInfo'] = this.shortInfo;
data['price'] = this.price;
if (this.publishedDate != null) {
data['publishedDate'] = this.publishedDate;
}
data['thumbnailUrl'] = this.thumbnailUrl;
data['longDescription'] = this.longDescription;
data['status'] = this.status;
return data;
}
}
class PublishedDate {
String? date;
PublishedDate({required this.date});
PublishedDate.fromJson(Map<String, dynamic> json) {
date = json['$date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['$date'] = this.date;
return data;
}
}
firestore image
New Errors after updated code
UPADTED ERRORS AGAIN
When I click on an error line in console stack it take me to my main.dart
When I click on the #2 error line in console stack it takes me to a file named 'framwork.dart'
And When I click on the #3rd error line it again takes me to a fucntion in 'framwork.dart'file
adminlogin.dart(here admin gets the button to upload items on firebasefirestore)
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:ecom_app/Authentication/AuthnticationScreen.dart';
import 'package:ecom_app/DialogBox/errordialog.dart';
import 'package:ecom_app/Widgets/CustomTextField.dart';
import 'package:flutter/material.dart';
import 'Uploaditems.dart';
class Adminsignin extends StatelessWidget {
const Adminsignin({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
),
title: Text
(
'E-Shop',
style: TextStyle(
fontSize:55.0,color: Colors.white),
),
centerTitle: true,
),
body: AdminSignInPage(),
);
}
}
class AdminSignInPage extends StatefulWidget {
const AdminSignInPage({Key? key}) : super(key: key);
@override
_AdminSignInPageState createState() => _AdminSignInPageState();
}
class _AdminSignInPageState extends State<AdminSignInPage> {
final TextEditingController _adminController =TextEditingController();
final TextEditingController _passwordController =TextEditingController();
final GlobalKey<FormState> _formKey=GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
double _screenwidth=MediaQuery.of(context).size.width,_screenHeight=MediaQuery.of(context).size.height;
return SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
alignment: Alignment.bottomCenter,
child: Image.asset(
'images/welcome.png',
height: 240.0,
width: 240.0,
),
),
Padding(
padding:EdgeInsets.all(8.0),
child: Text('Admin',
style: TextStyle(color: Colors.white38,fontSize: 28.0,fontWeight: FontWeight.bold),
),
),
Form(
key: _formKey,
child: Column(
children: [
customtextfield(
controller: _adminController,
data: Icons.person,
hinttext: 'ID',
isObsecure:false,
),
customtextfield(
controller: _passwordController,
data: Icons.lock,
hinttext: 'Password',
isObsecure:true,
),
SizedBox(
height: 25.0,
),
ElevatedButton(
onPressed: ()=>
_adminController.text.isNotEmpty&&_passwordController.text.isNotEmpty
? loginAdmin ()
:showDialog(
context: context,
builder: (c){
return ErrorDialog(message: 'Please Enter ID and Password');
}
),
style: ElevatedButton.styleFrom(primary: Colors.pink,onPrimary: Colors.yellow),
child:Text("Login"),
),
SizedBox(
height: 50.0,
),
Container(
height: 4.0,
width: _screenwidth*0.8,
color: Colors.pink,
),
SizedBox(
height: 10.0,
),
FlatButton.icon(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>AuthenticScreen( )));
},
icon: Icon(Icons.admin_panel_settings,color: Colors.pink,),
label: Text('I am not an Admin',style: TextStyle(color: Colors.pink,fontWeight: FontWeight.bold),),
),
SizedBox(
height: 50.0,
),
],
)
),
],
),
),
);
}
loginAdmin () {
FirebaseFirestore.instance.collection('admins').get().then((snapshot){
snapshot.docs.forEach((result){
if(result.data()['id'] != _adminController.text.trim())
{
Scaffold.of(context).showSnackBar(SnackBar(content: Text('ID is not Correct')));
}
else if(result.data()['password'] != _passwordController.text.trim())
{
Scaffold.of(context).showSnackBar(SnackBar(content: Text('Passwod is not Correct')));
}
else
{
Scaffold.of(context).showSnackBar(SnackBar(content: Text('Welcome Admin, ' +result.data()['name'],)));
setState(() {
_adminController.text='';
_passwordController.text='';
});
Route route=MaterialPageRoute(builder: (c)=> UploadPage());
Navigator.pushReplacement(context, route);
}
});
});
}
}