Ill try and provide as much code as possible. (mainly regarding the image ill be using "other data" instead of posting non needed code besides the image)
So in my app I have a File image;
provider and im having issues with getting to display it on my app. Im unable to pass the File
image path into firebase
and its causing my app to crash when I try Fetching
the data from firebase. Ill try providing as much code as possible.
Here is my provider:
import 'dart:io';
class AddCar {
// other data
File image;
AddCar({
// other data
this.image,
});
}
Here is my provider code:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:io';
import '../add_ons/add_car.dart';
List<AddCar> _cars = [];
class Cars with ChangeNotifier {
List<AddCar> get cars {
return [..._cars];
}
Future<void> fetchAndSetCars() async {
const url = 'https://mycustomlink.firebaseio.com/cars.json';
try {
final response = await http.get(url);
final extractedData = json.decode(response.body) as Map<String, dynamic>;
var loadedCars = extractedData
.map<String, AddCar>((carId, carData) => MapEntry(
carId,
AddCar(
// other data
image: File(carData['image']),
)))
.values
.toList();
_cars = loadedCars;
print(extractedData);
print(loadedCars);
notifyListeners();
} catch (error) {
throw (error);
}
}
AddCar findById(String id) {
return _cars.firstWhere((carProd) => carProd.id == id);
}
void addCar(AddCar car) {
const url = 'https://mycustomlink.firebaseio.com/cars.json';
http.post(
url,
body: json.encode({
// other data
'image': car.image.toString(),
}),
);
final newCar = AddCar(
// other data
image: car.image,
);
_cars.insert(0, newCar);
notifyListeners();
}
}
here is my form
where the user enters data for it to be displayed:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_app/app_localization.dart';
import 'package:google_fonts_arabic/fonts.dart';
import 'package:provider/provider.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart' as syspaths;
import '../add_ons/add_car.dart';
import '../providers/car_provider.dart';
import '../drawer/drawer.dart';
import '../screens/cars_screen.dart';
import '../app_localization.dart';
class CreateCar extends StatefulWidget {
static const routeName = '/create-car';
@override
_CreateCarState createState() => _CreateCarState();
}
class _CreateCarState extends State<CreateCar> {
final _name = TextEditingController();
final _price = TextEditingController();
final _address = TextEditingController();
String img;
static Future<String> fileToB64(File f) async {
List<int> imageBytes = f.readAsBytesSync();
return base64Encode(
imageBytes,
);
}
Future<void> _takePicture() async {
final imageFile = await ImagePicker.pickImage(
source: ImageSource.gallery,
);
fileToB64(data.image).then((d) {
setState(() {
img = d; //base64Decode(d);
});
});
}
final _form = GlobalKey<FormState>();
int currStep = 0;
static AddCar data = new AddCar(
id: null,
date: DateTime.now(),
sponsNum: '',
);
void _saveForm() {
final isValid = _form.currentState.validate();
if (!isValid) {
return;
}
_form.currentState.save();
Provider.of<Cars>(context, listen: false).addCar(data);
Navigator.of(context).pushNamed(CarsScreen.routeName);
print('this works');
}
@override
Widget build(BuildContext context) {
List<Step> steps = [
Step(
title: Text(
AppLocalizations.of(context).createTabTitle,
),
isActive: true,
state: StepState.indexed,
content: Column(
children: <Widget>[
// other data
],
),
),
Step(
title: Text(
AppLocalizations.of(context).createCarDetails,
),
isActive: true,
state: StepState.indexed,
content: Column(
children: <Widget>[
// other data
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 25.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Theme.of(context).primaryColor),
borderRadius: BorderRadius.circular(50.0),
),
child: FlatButton(
child: Text(AppLocalizations.of(context).createAddImages),
onPressed: _takePicture,
),
),
)
],
)
],
),
),
];
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
AppLocalizations.of(context).createCarPageTitle,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: ArabicFonts.Tajawal,
package: 'google_fonts_arabic',
),
),
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: _saveForm,
),
IconButton(
icon: Icon(Icons.arrow_forward),
onPressed: () {
Navigator.of(context).pop();
},
)
],
),
],
),
drawer: MyDrawer(),
body: Row(
children: <Widget>[
Form(
key: _form,
child: Expanded(
child: Stepper(
steps: steps,
type: StepperType.vertical,
currentStep: this.currStep,
onStepContinue: () {
setState(() {
if (currStep < steps.length - 1) {
currStep = currStep + 1;
} else {
// currStep = 0;
}
});
},
onStepCancel: () {
setState(() {
if (this.currStep > 0) {
this.currStep = this.currStep - 1;
} else {
this.currStep = 0;
}
});
},
onStepTapped: (step) {
setState(() {
currStep = step;
});
},
),
),
),
],
),
);
}
}
which is later passed into my "CarItem" that will display my code:
import 'package:flutter/material.dart';
import 'package:google_fonts_arabic/fonts.dart';
import '../icons/MyIcons.dart';
import 'dart:io';
import '../details/car_details.dart';
import '../app_localization.dart';
class CarItem extends StatelessWidget {
final File image;
CarItem(
this.image,
);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Theme.of(context).primaryColor, width: 2.0),
),
),
child: Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Color.fromARGB(255, 245, 245, 245),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(17.0, 4.0, 17.0, 4.0),
child: Row(
textDirection: TextDirection.rtl,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
// other data
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width * 0.35,
height: MediaQuery.of(context).size.width * 0.35,
child: GestureDetector(
child: Image.file(
image,
fit: BoxFit.fill,
),
onTap: () {
Navigator.of(context).pushNamed(
MyCarDetails.routeName,
arguments: id,
);
},
),
),
Container(
width: MediaQuery.of(context).size.width * 0.65,
margin: EdgeInsets.all(0),
padding: const EdgeInsets.fromLTRB(22.0, 5.0, 22.0, 0),
child: Column(
children: <Widget>[
// other data
],
),
),
],
),
),
],
),
],
),
);
}
}
this code gets called by a list that will call the code and display it in my app:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:google_fonts_arabic/fonts.dart';
import '../providers/car_provider.dart';
import '../widget/car_item.dart';
class CarsList extends StatefulWidget {
@override
_CarsListState createState() => _CarsListState();
}
class _CarsListState extends State<CarsList> {
@override
Widget build(BuildContext context) {
final carsData = Provider.of<Cars>(context);
final car = carsData.cars;
return car.isEmpty
? Center(
child: Text(
'no data yet available',
style: TextStyle(
fontFamily: ArabicFonts.Tajawal,
fontWeight: FontWeight.bold,
package: 'google_fonts_arabic',
),
))
: ListView.builder(
padding: const EdgeInsets.only(bottom: 47.0),
itemCount: car.length,
itemBuilder: (ctx, i) => CarItem(
// other data
car[i].image,
),
);
}
}
this is the error i keep getting when It tries to display fetched data:
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building CarItem(dirty, dependencies: [_LocalizationsScope-[GlobalKey#31697], MediaQuery, _InheritedTheme]):
The method '+' was called on null.
Receiver: null
Tried calling: +("25")
User-created ancestor of the error-causing widget was
ListView
lib\home_parts\cars_area.dart:49
When the exception was thrown, this was the stack
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 CarItem.build
package:flutter_app/widget/car_item.dart:151
#2 StatelessElement.build
package:flutter/…/widgets/framework.dart:4009
#3 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:3941
#4 Element.rebuild
package:flutter/…/widgets/framework.dart:3738
...
════════════════════════════════════════════════════════════════════════════════
How can I fix this? is the issue in how im passing the data to firebase and displaying it on my app?