Flutter: Bad state Error: cannot get a field on a DocumentSnapshotPlatform which does not exist - flutter

I'm new to Flutter and getting this issue.
Trying to develop a social media app which includes a chat feature. However, it says DocumentSnapshot is not exist.
Of course I understood that one thing is missing, it is clear. But I couldn't understand what is that missing thing and how to solve it.
I examined a lot of posts about this but I couldn't solve my issue. There is no misspelling between Cloud Firestore and my code. I couldn't understand am I missing key or something like this?
It looks like this
Sometimes it also can not upload the profile picture of person.
Here are my codes,
Thanks for helping.
I got this error when I try to type a message:
class Conversation extends StatefulWidget {
final String userId;
final String chatId;
const Conversation({required this.userId, required this.chatId});
#override
_ConversationState createState() => _ConversationState();
}
class _ConversationState extends State<Conversation> {
FocusNode focusNode = FocusNode();
ScrollController scrollController = ScrollController();
TextEditingController messageController = TextEditingController();
bool isFirst = false;
String? chatId;
#override
void initState() {
super.initState();
scrollController.addListener(() {
focusNode.unfocus();
});
print(widget.chatId);
if (widget.chatId == 'newChat') {
isFirst = true;
}
chatId = widget.chatId;
messageController.addListener(() {
if (focusNode.hasFocus && messageController.text.isNotEmpty) {
setTyping(true);
} else if (!focusNode.hasFocus ||
(focusNode.hasFocus && messageController.text.isEmpty)) {
setTyping(false);
}
});
}
setTyping(typing) {
//here
UserViewModel viewModel =
Provider.of<UserViewModel>(context, listen: false);
viewModel.setUser();
//here
var user = Provider.of<UserViewModel>(context, listen: false).user;
Provider.of<ConversationViewModel>(context, listen: false)
.setUserTyping(widget.chatId, user, typing);
}
#override
Widget build(BuildContext context) {
UserViewModel viewModel =
Provider.of<UserViewModel>(context, listen: false);
viewModel.setUser();
var user = Provider.of<UserViewModel>(context, listen: true).user;
return Consumer<ConversationViewModel>(
builder: (BuildContext context, viewModel, Widget? child) {
return Scaffold(
key: viewModel.scaffoldKey,
appBar: AppBar(
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.keyboard_backspace,
),
),
elevation: 0.0,
titleSpacing: 0,
title: buildUserName(),
),
body: Container(
height: MediaQuery.of(context).size.height,
child: Column(
children: [
Flexible(
child: StreamBuilder<QuerySnapshot>(
stream: messageListStream(widget.chatId),
builder: (context, snapshot) {
if (snapshot.hasData) {
//snapshot.hasData
//print(snapshot.data);
print(viewModel);
List messages = snapshot.data!.docs;
viewModel.setReadCount(
widget.chatId, user, messages.length);
return ListView.builder(
controller: scrollController,
padding: EdgeInsets.symmetric(horizontal: 10.0),
itemCount: messages.length,
reverse: true,
itemBuilder: (BuildContext context, int index) {
Message message = Message.fromJson(
messages.reversed.toList()[index].data(),
);
print(message.content);
print(message.senderUid);
print(message.time);
print(message.type);
return ChatBubble(
message: '${message.content}',
time: message.time!,
isMe: message.senderUid == user!.uid,
type: message.type!,
);
},
);
} else {
return Center(child: circularProgress(context));
}
},
),
),
Align(
alignment: Alignment.bottomCenter,
child: BottomAppBar(
elevation: 10.0,
child: Container(
constraints: BoxConstraints(maxHeight: 100.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
IconButton(
icon: Icon(
CupertinoIcons.photo_on_rectangle,
color: Theme.of(context).colorScheme.secondary,
),
onPressed: () => showPhotoOptions(viewModel, user),
),
Flexible(
child: TextField(
controller: messageController,
focusNode: focusNode,
style: TextStyle(
fontSize: 15.0,
color:
Theme.of(context).textTheme.headline6!.color,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
enabledBorder: InputBorder.none,
border: InputBorder.none,
hintText: "Type your message",
hintStyle: TextStyle(
color: Theme.of(context)
.textTheme
.headline6!
.color,
),
),
maxLines: null,
),
),
IconButton(
icon: Icon(
Ionicons.send,
color: Theme.of(context).colorScheme.secondary,
),
onPressed: () {
if (messageController.text.isNotEmpty) {
sendMessage(viewModel, user);
}
},
),
],
),
),
),
)
],
),
),
);
});
}
_buildOnlineText(
var user,
bool typing,
) {
if (user.isOnline) {
if (typing) {
return "typing...";
} else {
return "online";
}
} else {
return 'last seen ${timeago.format(user.lastSeen.toDate())}';
}
}
buildUserName() {
return StreamBuilder(
stream: usersRef.doc('${widget.userId}').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
DocumentSnapshot documentSnapshot =
snapshot.data as DocumentSnapshot<Object?>;
UserModel user = UserModel.fromJson(
documentSnapshot.data() as Map<String, dynamic>,
);
return InkWell(
child: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 10.0, right: 10.0),
child: Hero(
tag: user.email!,
child: CircleAvatar(
radius: 25.0,
backgroundImage: CachedNetworkImageProvider(
'${user.photoUrl}',
),
),
),
),
SizedBox(width: 10.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'${user.username}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
),
SizedBox(height: 5.0),
StreamBuilder(
stream: chatRef.doc('${widget.chatId}').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
DocumentSnapshot? snap =
snapshot.data as DocumentSnapshot<Object?>;
Map? data = snap.data() as Map<dynamic, dynamic>?;
Map? usersTyping = data?['typing'] ?? {};
return Text(
_buildOnlineText(
user,
usersTyping![widget.userId] ?? false,
),
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 11,
),
);
} else {
return SizedBox();
}
},
),
],
),
),
],
),
onTap: () {},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
showPhotoOptions(ConversationViewModel viewModel, var user) {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
builder: (context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text("Camera"),
onTap: () {
sendMessage(viewModel, user, imageType: 0, isImage: true);
},
),
ListTile(
title: Text("Gallery"),
onTap: () {
sendMessage(viewModel, user, imageType: 1, isImage: true);
},
),
],
);
},
);
}
sendMessage(ConversationViewModel viewModel, var user,
{bool isImage = false, int? imageType}) async {
String msg;
if (isImage) {
msg = await viewModel.pickImage(
source: imageType!,
context: context,
chatId: widget.chatId,
);
} else {
msg = messageController.text.trim();
messageController.clear();
}
Message message = Message(
content: '$msg',
senderUid: user?.uid,
type: isImage ? MessageType.IMAGE : MessageType.TEXT,
time: Timestamp.now(),
);
if (msg.isNotEmpty) {
if (isFirst) {
print("FIRST");
String id = await viewModel.sendFirstMessage(widget.userId, message);
setState(() {
isFirst = false;
chatId = id;
});
} else {
viewModel.sendMessage(
widget.chatId,
message,
);
}
}
}
Stream<QuerySnapshot> messageListStream(String documentId) {
return chatRef
.doc(documentId)
.collection('messages')
.orderBy('time')
.snapshots();
}
}
Also here is the ViewModel codes if I did something wrong here:
class ConversationViewModel extends ChangeNotifier {
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
ChatService chatService = ChatService();
bool uploadingImage = false;
final picker = ImagePicker();
File? image;
sendMessage(String chatId, Message message) {
chatService.sendMessage(
message,
chatId,
);
}
Future<String> sendFirstMessage(String recipient, Message message) async {
String newChatId = await chatService.sendFirstMessage(
message,
recipient,
);
return newChatId;
}
setReadCount(String chatId, var user, int count) {
chatService.setUserRead(chatId, user, count);
}
setUserTyping(String chatId, var user, bool typing) {
chatService.setUserTyping(chatId, user, typing);
}
pickImage({int? source, BuildContext? context, String? chatId}) async {
PickedFile? pickedFile = source == 0
? await picker.getImage(
source: ImageSource.camera,
)
: await picker.getImage(
source: ImageSource.gallery,
);
if (pickedFile != null) {
CroppedFile? croppedFile = await ImageCropper().cropImage(
sourcePath: pickedFile.path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
],
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Crop image',
toolbarColor: Theme.of(context!).appBarTheme.backgroundColor,
toolbarWidgetColor: Theme.of(context).iconTheme.color,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
IOSUiSettings(
minimumAspectRatio: 1.0,
),
],
);
Navigator.of(context).pop();
if (croppedFile != null) {
uploadingImage = true;
image = File(croppedFile.path);
notifyListeners();
showInSnackBar("Uploading image...", context);
String imageUrl = await chatService.uploadImage(image!, chatId!);
return imageUrl;
}
}
}
void showInSnackBar(String value, context) {
ScaffoldMessenger.of(context).removeCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(value),
),
);
}
}
Here is the ChatService code:
class ChatService {
FirebaseStorage storage = FirebaseStorage.instance;
sendMessage(Message message, String chatId) async {
//will send message to chats collection with the usersId
await chatRef.doc("$chatId").collection("messages").add(message.toJson());
//will update "lastTextTime" to the last time a text was sent
await chatRef.doc("$chatId").update({"lastTextTime": Timestamp.now()});
}
Future<String> sendFirstMessage(Message message, String recipient) async {
User user = firebaseAuth.currentUser!;
DocumentReference ref = await chatRef.add({
'users': [recipient, user.uid],
});
await sendMessage(message, ref.id);
return ref.id;
}
Future<String> uploadImage(File image, String chatId) async {
Reference storageReference =
storage.ref().child("chats").child(chatId).child(uuid.v4());
UploadTask uploadTask = storageReference.putFile(image);
await uploadTask.whenComplete(() => null);
String imageUrl = await storageReference.getDownloadURL();
return imageUrl;
}
//determine if a user has read a chat and updates how many messages are unread
setUserRead(String chatId, User user, int count) async {
DocumentSnapshot snap = await chatRef.doc(chatId).get();
Map reads = snap.get('reads') ?? {};
reads[user.uid] = count;
await chatRef.doc(chatId).update({'reads': reads});
}
//determine when a user has start typing a message
setUserTyping(String chatId, User user, bool userTyping) async {
DocumentSnapshot snap = await chatRef.doc(chatId).get();
Map typing = snap.get('typing');
typing[user.uid] = userTyping;
await chatRef.doc(chatId).update({
'typing': typing,
});
}
}

Related

Flutter Firebase Realtime Database.Streambuilder and listview.builder returns error Index out of range: index should be less

i am using Flutter and Firebase to build an order app.I'm using Realtime Database and a streambuilder to fetch the data and every update and listview.builder to portray them.
When i display the data works fine but the problem is that when i am trying to expand the data in the RTDB i'm getting this error
Another exception was thrown: RangeError (index): Index out of range: index should be less than 22: 22.
I'm trying to expand the data on another page.Sorry if my question is a bit of a crap i am asking for the first time
Scaffold(
body: StreamBuilder(
stream: ref.onValue,
builder: (context, snapshot) {
if(
snapshot.hasData &&
snapshot.data != null &&
(snapshot.data! as DatabaseEvent).snapshot.children !=
null){
List<Orderlist> listorder = [];
final myorders = snapshot.data!.snapshot.children;
myorders.forEach((numoftable) {
count+=1;
String payment_state = '';
String payment_method = '';
List<Order> orders=[];
final number_of_orders = numoftable.children.length;
numoftable.children.forEach((order) {
if(order.key=='payment_state') payment_state=order.value.toString();
if(order.key=='payment_method') payment_method=order.value.toString();
List<Orderitem> orderitems = [];
final order_id = order.key.toString();
// print(order_id);
if(order_id.length<=3){
final node = order.value as Map<dynamic,dynamic>?;
String temp_pending='';
String temp_payment='';
String customer_uid='';
node!.forEach((keys,values) {
// orderitem.name = element;
if(keys!='description' && keys!='customer_uid'){
final value = values as Map<String,dynamic>;
String price='';
String description='';
String number_of_appereance='';
value.forEach((key, value) {
if(key=='price') price=value.toString();
if(key=='description') description=value;
if(key=='number of appereances') number_of_appereance = value.toString();
});
final orderitem = Orderitem(name: keys,price: price,description: description,number_of_appereance: number_of_appereance);
orderitems.add(orderitem);
}
if(keys=='description'){
temp_pending = values.toString();
}
if(keys=='customer_uid'){
customer_uid=values.toString();
}
},);
final nextorder = Order(number_of_table: int.tryParse(numoftable.key.toString()),
items: orderitems,order_ids: order_id,customer_uid: customer_uid,
pending: temp_pending,);
orders.add(nextorder);
}
});
final current_index = int.parse(numoftable.key.toString())-1;
`your text`
if(temp_length.isEmpty || count<=myorders.length){
temp_length.insert(current_index, orders.length);
}
else if(temp_length[current_index]<orders.length ){
temp_length[current_index]= orders.length;
ref.child(numoftable.key.toString()).update({'payment_state':'Not payed'});
ref.child(numoftable.key.toString()).update({'payment_method':'Cash'});
}
final nextorderlist = Orderlist(
orderlist: orders,
number_of_table: numoftable.key.toString(),
payment_state: payment_state,
payment_method: payment_method,
number_of_orders: number_of_orders);
// print(nextorder.order_ids);
listorder.add(nextorderlist);
// ref.child(numoftable.key.toString()).update({'check':'false'});
},
);
return Column(
children: [
GeneralSettings(),
Flexible(
child: GridView.builder(
shrinkWrap: true,
itemCount: listorder.length ,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (context, index) {
return _listoforders(listorder, index,);
},
),
),
],
);
}else if(snapshot.connectionState==ConnectionState.waiting){
Center(child: CircularProgressIndicator(),);
}
else if(snapshot.hasError){
return Text('Error');
}
return Text('Error');
}
),
);
}
Widget _listoforders(List<Orderlist> listoforders,int index) {
return GestureDetector(
onTap: (){
orders.clear();
listoforders[index].orderlist!.forEach((element) { orders.add(element); });
context.goNamed('Details');
},
child: Container(
color:listoforders[index].payment_state=='None' ? Colors.lightBlue : (listoforders[index].payment_state=='Not payed') ? Colors.red : Colors.green,
child: Column(
children: [
ListTile(title: Text(listoforders[index].number_of_table.toString()),
subtitle: listoforders[index].payment_state=='None' ? Icon(Icons.no_food) : listoforders[index].payment_state=='Not payed' ? Icon(Icons.money_off) : Text('Payed'),
trailing: IconButton(onPressed: () {
listoforders[index].orderlist!.forEach((element) {
setState(() {
temp_length[index]=0;
ref.child(listoforders[index].number_of_table.toString()).child(element.order_ids!).remove();
ref.child(listoforders[index].number_of_table.toString()).update({'payment_state':'None'});
ref.child(listoforders[index].number_of_table.toString()).update({'payment_method':'None'});
delete(element.customer_uid!);
});
});
}, icon: Icon(Icons.delete)),
leading: (listoforders[index].payment_method=='None' ) ? Text('No payment method') : (listoforders[index].payment_method=='With card' ) ? Icon(Icons.credit_card) : Icon(Icons.money_rounded),),
Flexible(
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: listoforders[index].orderlist!.length,
itemBuilder: (context, current_index) {
final current_order = listoforders[index].orderlist![current_index];
return Container(
color: current_order.pending=='Unchecked' ? Colors.red : (current_order.pending=='pending') ? Colors.amber : Colors.green,
child: ListTile(
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context)=>OrderSettings(order: current_order))),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(current_order.order_ids!),
],
),
subtitle: Text(current_order.pending!),
trailing: current_order.pending=='Unchecked' ? IconButton(onPressed: () => setState(() {
ref.child(current_order.number_of_table.toString()).child(current_order.order_ids!).update({"description":"pending"});
}) , icon: Icon(Icons.alarm_add)) :
current_order.pending=='pending' ? IconButton(onPressed: () => setState(() {
ref.child(current_order.number_of_table.toString()).child(current_order.order_ids!).update({"description":"Done"});
}) , icon: Icon(Icons.pending_actions)) : Icon(Icons.check),
leading: IconButton(onPressed:() {
ref.child(current_order.number_of_table.toString()).child(current_order.order_ids!).remove();
} ,
icon:Icon(Icons.delete) ,),
),
);
},),
),
],
),
),
);}
}
Future delete(String uid) async{
final doc = FirebaseFirestore.instance.collection('Customers').doc(uid);
await doc.update({'order':''});
}
I am updating the RTDB on this page
class UpdatePanel extends StatefulWidget {
String? name;
bool check;
int? tables;
UpdatePanel({super.key,this.name,required this.check, this.tables});
#override
State<UpdatePanel> createState() => _UpdatePanelState();
}
class _UpdatePanelState extends State<UpdatePanel> {
late DatabaseReference ref;
TextEditingController namecontroller = TextEditingController();
TextEditingController number_of_tables = TextEditingController();
#override
void initState() {
// TODO: implement initState
ref=FirebaseDatabase.instance.ref().child(widget.name!);
super.initState();
}
#override
Widget build(BuildContext context) {
print(widget.name);
print(widget.tables);
Size size = MediaQuery.of(context).size;
final futurefiles = FirebaseStorage.instance.ref().child('${widget.name}/');
return AlertDialog(
title: Text(widget.check? 'Update businness name':'Update tables number'),
content: Container(
height: size.height*0.3,
child: SingleChildScrollView(
child: Column(children: [
widget.check ?
Textwidget(controller: namecontroller, hinttext: 'Update name', labeltext: 'Name', icon: Icon(Icons.business_center), color: Colors.black) :
Textwidget(controller: number_of_tables, hinttext: 'Update number of tables', labeltext: 'Number of tables', icon: Icon(Icons.table_bar), color: Colors.black),
SizedBox(height: size.height*0.05,),
ElevatedButton.icon(onPressed: () {
setState(() {
DatabaseManager(displayName: widget.name).settabledata(int.parse(number_of_tables.text.trim()));
createQrcodes();
resetRTDB();
(context as Element).reassemble();
Navigator.pop(context);
});
}, icon: Icon(Icons.update), label: Text('Update'))
]),
),
),
actions: [
OutlinedButton(onPressed: () => Navigator.pop(context), child: Text('Close'))
],
);
}
void resetRTDB() async{
for(int i=widget.tables!+1;i<=int.parse(number_of_tables.text.trim());i++){
await ref.child('${i}').set({"payment_state":"None","payment_method":"None",});
}
}
Future<Uint8List> toQrImageData(String text) async {
try {
final image = await QrPainter(
data: text,
version: QrVersions.auto,
gapless: false,
color: Colors.black,
emptyColor: Colors.white,
).toImage(300);
final a = await image.toByteData(format: ImageByteFormat.png);
return a!.buffer.asUint8List();
} catch (e) {
throw e;
}
}
Future createQrcodes() async{
for(int i=widget.tables!+1;i<=int.parse(number_of_tables.text.trim());i++){
final path = '${widget.name!.trim()}/${i}';
final ref = FirebaseStorage.instance.ref().child(path);
final file = await toQrImageData(widget.name!.trim().toLowerCase()+' '+'${i}');
ref.putData(file,SettableMetadata(contentType: 'image/png'));
}
}
}
this is where your error occurs
void resetRTDB() async{
for(int i=widget.tables!+1;i<=int.parse(number_of_tables.text.trim());i++){
await ref.child('${i}').set({"payment_state":"None","payment_method":"None",});
}
after getting all the data and it tries to get new data by adding 1 in every time ,change try changing your logic here

Why does Flutter Camera Plugin return video content type as Application/octet-stream

hello guys!
i am using flutter story view package to implement story functionality in my app and i am using camera plugin to record video and upload, however the content type of the uploaded video is application/octet-stream when i receive it on my server and only when it is sent from ios. for android everything is fine and i get the content type as video/mp4.
can you guys please help me.
i have not done anything fancy i have just used the basic functionality of start recording and stop recording of the camra plugin.
// ignore_for_file: use_build_context_synchronously
List<CameraDescription>? cameras;
class CameraScreen extends StatefulWidget {
const CameraScreen({Key? key}) : super(key: key);
#override
State<CameraScreen> createState() => _CameraScreenState();
}
class _CameraScreenState extends State<CameraScreen> {
CameraController? _cameraController;
Future<void>? cameraValue;
bool flash = false;
bool iscamerafront = true;
static const _maxSeconds = 30;
ValueNotifier<bool> visible = ValueNotifier(false);
ValueNotifier<bool> isRecoring = ValueNotifier(false);
TimerProvider? _timerProvider;
#override
void initState() {
super.initState();
_timerProvider = Provider.of(context, listen: false);
_cameraController = CameraController(cameras![0], ResolutionPreset.veryHigh,
imageFormatGroup: ImageFormatGroup.bgra8888);
cameraValue = _cameraController?.initialize();
_cameraController?.prepareForVideoRecording();
lockCamera();
}
lockCamera() async {
await _cameraController!.lockCaptureOrientation();
}
#override
void dispose() {
super.dispose();
visible.dispose();
isRecoring.dispose();
_cameraController?.dispose();
}
#override
Widget build(BuildContext context) {
print("camera_screen");
final size = MediaQuery.of(context).size;
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
centerTitle: true,
title: ValueListenableBuilder<bool>(
valueListenable: visible,
builder: (context, value, child) {
return Visibility(
visible: value,
child: Container(
padding: const EdgeInsets.all(10),
width: 50,
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.5)),
child: Center(
child: Consumer<TimerProvider>(
builder: (context, value, child) {
if (value.seconds == 0) {
if (_cameraController!.value.isRecordingVideo) {
stopRecording();
}
}
return Text(
value.seconds.toString(),
style: CustomStyles.fixAppBarTextStyle
.copyWith(color: Colors.white),
);
}),
),
));
}),
backgroundColor: Colors.transparent,
leadingWidth: 100,
leading: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Cancel",
style: CustomStyles.fixMediumBodyTextStyle
.copyWith(color: Colors.white),
),
)),
),
),
body: SafeArea(
top: false,
child: Stack(
children: [
FutureBuilder(
future: cameraValue,
builder: (context, snapshot) {
_cameraController?.lockCaptureOrientation();
if (snapshot.connectionState == ConnectionState.done) {
return Transform.scale(
scale: size.aspectRatio *
_cameraController!.value.aspectRatio <
1
? 1 /
(size.aspectRatio *
_cameraController!.value.aspectRatio)
: size.aspectRatio *
_cameraController!.value.aspectRatio,
child: Center(child: CameraPreview(_cameraController!)),
);
} else {
return const Center(
child: CircularProgressIndicator.adaptive(),
);
}
}),
Positioned(
bottom: 0.0,
child: Container(
padding: const EdgeInsets.only(top: 5, bottom: 5),
width: Dimensions.screenWidth,
child: Column(
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.5)),
child: Center(
child: IconButton(
icon: Icon(
flash ? Icons.flash_on : Icons.flash_off,
color: Colors.white,
size: 28,
),
onPressed: () {
setState(() {
flash = !flash;
});
flash
? _cameraController!
.setFlashMode(FlashMode.torch)
: _cameraController!
.setFlashMode(FlashMode.off);
}),
),
),
ValueListenableBuilder<bool>(
valueListenable: isRecoring,
builder: (context, value, child) {
return GestureDetector(
onLongPress: () {
startRecording();
},
onLongPressUp: () {
stopRecording();
},
onTap: () {
if (value == false) {
takePhoto(context);
}
},
child: value == true
? const CircleAvatar(
radius: 50,
backgroundColor: Colors.white30,
child: CircleAvatar(
radius: 35,
backgroundColor: Colors.red,
),
)
: const CircleAvatar(
radius: 35,
backgroundColor: Colors.white30,
child: CircleAvatar(
radius: 25,
backgroundColor: Colors.white,
),
));
}),
Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.5)),
child: IconButton(
icon: const Icon(
Icons.flip_camera_ios,
color: Colors.white,
size: 28,
),
onPressed: () async {
setState(() {
iscamerafront = !iscamerafront;
});
int cameraPos = iscamerafront ? 0 : 1;
_cameraController = CameraController(
cameras![cameraPos], ResolutionPreset.high);
cameraValue = _cameraController?.initialize();
}),
),
],
),
addVerticalSpace(6),
const Text(
"Hold for Video, tap for photo",
style: TextStyle(
color: Colors.white,
),
textAlign: TextAlign.center,
),
addVerticalSpace(5),
],
),
),
),
],
),
),
);
}
void startRecording() async {
visible.value = true;
_timerProvider?.startCountDown(_maxSeconds);
isRecoring.value = true;
await _cameraController?.startVideoRecording();
}
void stopRecording() async {
XFile videopath = await _cameraController!.stopVideoRecording();
_timerProvider?.stopTimer();
isRecoring.value = false;
Navigator.push(
context,
MaterialPageRoute(
builder: (builder) => CameraResult(
image: File(videopath.path),
isImage: false,
))).then((value) {
visible.value = false;
});
}
void takePhoto(BuildContext context) async {
XFile file = await _cameraController!.takePicture();
SystemSound.play(SystemSoundType.click);
final img.Image? capturedImage =
img.decodeImage(await File(file.path).readAsBytes());
final img.Image orientedImage = img.flipHorizontal(capturedImage!);
File finalImage =
await File(file.path).writeAsBytes(img.encodeJpg(orientedImage));
Navigator.push(
context,
CupertinoPageRoute(
builder: (builder) => CameraResult(
image: finalImage,
isImage: true,
))).then((value) {
visible.value = false;
});
}
}
the upload function is as bellow
{File? shouts,
File? thumbnail,
int? duration,
bool? isImage,
required String userId,
required OnUploadProgressCallback onUploadProgress}) async {
assert(shouts != null);
try {
var url = Constants.POSTSHOUTURL;
final httpClient = FileService.getHttpClient();
final request = await httpClient.postUrl(Uri.parse(url));
int byteCount = 0;
var multipart;
if (isImage == false) {
multipart = await http.MultipartFile.fromPath(
'story-media', shouts!.path,
contentType: MediaType("video", "mp4"));
} else {
multipart = await http.MultipartFile.fromPath(
'story-media',
shouts!.path,
);
}
var multipart2 =
await http.MultipartFile.fromPath('thumbnail', thumbnail!.path);
var requestMultipart = http.MultipartRequest('POST', Uri.parse(url));
requestMultipart.fields["userid"] = userId.toString();
requestMultipart.fields["duration"] = duration.toString();
requestMultipart.headers['Content-type'] = 'multipart/form-data';
requestMultipart.files.add(multipart);
requestMultipart.files.add(multipart2);
var msStream = requestMultipart.finalize();
var totalByteLength = requestMultipart.contentLength;
request.contentLength = totalByteLength;
request.headers.add(HttpHeaders.authorizationHeader,
"Bearer ${Hive.box<UserData>(Constants.userDb).get(Hive.box<UserData>(Constants.userDb).keyAt(0))!.token}");
request.headers.set(HttpHeaders.contentTypeHeader,
requestMultipart.headers[HttpHeaders.contentTypeHeader]!);
Stream<List<int>> streamUpload = msStream.transform(
StreamTransformer.fromHandlers(
handleData: (data, sink) {
sink.add(data);
byteCount += data.length;
if (onUploadProgress != null) {
onUploadProgress(byteCount, totalByteLength);
// CALL STATUS CALLBACK;
}
},
handleError: (error, stack, sink) {
throw error;
},
handleDone: (sink) {
sink.close();
// UPLOAD DONE;
},
),
);
await request.addStream(streamUpload);
final httpResponse = await request.close();
var statusCode = httpResponse.statusCode;
if (statusCode ~/ 100 == 2) {
onUploadProgress(0, 0);
return await FileService.readResponseAsString(httpResponse);
}
return "";
} on SocketException {
throw FetchDataException("No internet to upload Shout!");
}
}```
i have used necessary info.plist setting also

RenderFlex children have non-zero flex but incoming height constraints are unbounded in flatter

I have a page code written in an android studio. On this page, I display a list of objects, as well as a widget to search for these objects. When I clicked on the search widget, I had the following problem: "The following statement was thrown during layout:
RenderFlex is overcrowded 31 pixels below.
The corresponding widget that caused the errors was: "But then I found the answer to this question and added" SingleChildScrollView ".
But then I had this problem: "RenderFlex have non-zero flexibility, but the input height limits are unlimited." . And I can't solve it in any way. I will be grateful for your help. Here is my code:
import 'package:flutter/material.dart';
import 'package:flutter_app_seals/model/post/form_unseals.dart';
import 'package:flutter_app_seals/model/post/form_seals.dart';
import 'package:flutter_app_seals/model/setting/globalvar.dart' as global;
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void main() => runApp(JsonParseObjectSts_UN());
class JsonParseObjectSts_UN extends StatefulWidget {
JsonParseObjectSts_UN() : super();
#override
_JsonParseObjectsState createState() => _JsonParseObjectsState();
}
class _JsonParseObjectsState extends State <StatefulWidget> {
List<UserDetails> _searchResult = [];
List<UserDetails> _userDetails = [];
TextEditingController controller = new TextEditingController();
final String url = global.urlVar ;
// Get json result and convert it to model. Then add
Future<Null> getUserDetails() async {
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
final request = await client
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 5));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
final responseJson = json.decode(responseBody);
setState(() {
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
}
#override
void initState() {
super.initState();
getUserDetails();
}
Widget _buildUsersList() {
return new ListView.builder(
itemCount: _userDetails.length,
itemBuilder: (context, index) {
return new Card(
color: (_userDetails[index].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_userDetails[index].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_userDetails[index].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _userDetails[index].sealed) {
global.nameObj = _userDetails[index].name,
global.sealsNumb = _userDetails[index].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _userDetails[index].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchResults() {
return new ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (context, i) {
return new Card(
color: (_searchResult[i].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_searchResult[i].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_searchResult[i].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _searchResult[i].sealed) {
global.nameObj = _searchResult[i].name,
global.sealsNumb = _searchResult[i].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _searchResult[i].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchBox() {
return new Padding(
padding: const EdgeInsets.all(8.0),
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Пошук', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
controller.clear();
onSearchTextChanged('');
},
),
),
),
);
}
Widget _buildBody() {
return new Scaffold(
body:Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.white],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child: SingleChildScrollView(
child:Column(
children: <Widget>[
new Container(
color: Theme.of(context).primaryColor, child: _buildSearchBox()),
new Expanded(
child: _searchResult.length != 0 || controller.text.isNotEmpty
? _buildSearchResults()
: _buildUsersList()),
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: _buildBody()
);
}
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_userDetails.forEach((userDetail) {
if (userDetail.name.contains(text) ) _searchResult.add(userDetail);
});
setState(() {});
}
}
class UserDetails {
final String name, seal_number,sealed;
UserDetails({this.name, this.sealed, this.seal_number});
factory UserDetails.fromJson(Map<String, dynamic> json) {
return new UserDetails(
sealed: json['sealed'],
name: json['name'],
seal_number: json['seal_number'],
);
}
}
My scrin:
My scrin when I want to use search:

how to increase the size of the window with the search result in flutter?

I have a page code written in an android studio. On this page, I display a list of objects, as well as a widget to search for these objects. When I clicked on the search widget,my list of objects is shrinking, and it is almost invisible (it is at the top). Can this be fixed somehow so that it can be seen on the whole page ??
import 'package:flutter/material.dart';
import 'package:flutter_app_seals/model/post/form_unseals.dart';
import 'package:flutter_app_seals/model/post/form_seals.dart';
import 'package:flutter_app_seals/model/setting/globalvar.dart' as global;
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void main() => runApp(JsonParseObjectSts_UN());
class JsonParseObjectSts_UN extends StatefulWidget {
JsonParseObjectSts_UN() : super();
#override
_JsonParseObjectsState createState() => _JsonParseObjectsState();
}
class _JsonParseObjectsState extends State <StatefulWidget> {
List<UserDetails> _searchResult = [];
List<UserDetails> _userDetails = [];
TextEditingController controller = new TextEditingController();
final String url = global.urlVar ;
// Get json result and convert it to model. Then add
Future<Null> getUserDetails() async {
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
final request = await client
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 5));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
final responseJson = json.decode(responseBody);
setState(() {
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
}
#override
void initState() {
super.initState();
getUserDetails();
}
Widget _buildUsersList() {
return new ListView.builder(
itemCount: _userDetails.length,
itemBuilder: (context, index) {
return new Card(
color: (_userDetails[index].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_userDetails[index].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_userDetails[index].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _userDetails[index].sealed) {
global.nameObj = _userDetails[index].name,
global.sealsNumb = _userDetails[index].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _userDetails[index].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchResults() {
return new ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (context, i) {
return new Card(
color: (_searchResult[i].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_searchResult[i].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_searchResult[i].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _searchResult[i].sealed) {
global.nameObj = _searchResult[i].name,
global.sealsNumb = _searchResult[i].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _searchResult[i].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchBox() {
return new Padding(
padding: EdgeInsets.all(7.0),
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Пошук', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
controller.clear();
onSearchTextChanged('');
},
),
),
),
);
}
Widget _buildBody() {
return new Scaffold(
body:Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.white],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child:Column(
children: <Widget>[
new Expanded( flex: 1, child: _buildSearchBox()),
new Expanded(flex:8,
child: _searchResult.length != 0 || controller.text.isNotEmpty
? _buildSearchResults()
: _buildUsersList()),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: _buildBody()
);
}
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_userDetails.forEach((userDetail) {
if (userDetail.name.contains(text) ) _searchResult.add(userDetail);
});
setState(() {});
}
}
class UserDetails {
final String name, seal_number,sealed;
UserDetails({this.name, this.sealed, this.seal_number});
factory UserDetails.fromJson(Map<String, dynamic> json) {
return new UserDetails(
sealed: json['sealed'],
name: json['name'],
seal_number: json['seal_number'],
);
}
}
My page:
My page with search:
I have looked at your code several times, I just noticed a small error.
For the results of your searches, you try to display the "List" of searches in a ListView.builder, which is in a column in the parent container does not have a defined height.
Solution: Set a height for the main container and the problem will be solved

Flutter image_picker package returns null when trying to retrieve a video from the gallery

I am trying to build an app that lets users select videos and upload them, so for this, I am using the image_picker package. However, I am currently running tests and whenever I try to select a video from the gallery, instead of getting a file back I get null. I don't know if the problem is with how I am using the package or with permissions, although according to the package you don't need permissions for android.
Below the function in my code that is giving me trouble:
handleChooseFromGallery() async {
Navigator.pop(context);
File filePicked = await ImagePicker.pickVideo(
source: ImageSource.gallery,
maxDuration: Duration(seconds: 90),
);
//This line always returns false
print({'is file not null': filePicked != null});
setState(() {
if (filePicked != null) {
this.files.add(filePicked);
this.selected = true;
} else {
showError();
}
});
}
The complete code (minus completely irrelevant things):
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:golfapp/data/course_data.dart';
import 'package:golfapp/data/user_data.dart';
import 'package:provider/provider.dart';
import 'package:image_picker/image_picker.dart';
import 'package:uuid/uuid.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:golfapp/data/semana_data.dart';
import 'package:golfapp/widgets/chewie_item.dart';
final StorageReference storageRef = FirebaseStorage.instance.ref();
final postsRef = Firestore.instance.collection('posts');
final DateTime timestamp = DateTime.now();
class DetailScreen extends StatefulWidget {
final int index;
final String photoUrl;
final String videoUrl;
DetailScreen({this.index, this.photoUrl, this.videoUrl});
#override
_DetailScreenState createState() => _DetailScreenState();
}
class _DetailScreenState extends State<DetailScreen> {
bool isUploading = false;
bool selected = false;
List<File> files = [];
String postId = Uuid().v4();
TextEditingController captionController = TextEditingController();
showError() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Row(
children: [
Padding(
padding: EdgeInsets.only(right: 10.0),
child: Text('Error'),
),
Icon(Icons.error_outline, size: 60.0),
],
),
content: SingleChildScrollView(
child: ListBody(
children: [
Text(
'Hubo un error con el video seleccionado.',
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w600,
fontSize: 17.0,
),
),
],
),
),
);
},
);
}
clearImage() {
setState(() {
this.selected = false;
});
}
handleTakePhoto() async {
Navigator.pop(context);
File fileTaken = await ImagePicker.pickVideo(
source: ImageSource.camera,
maxDuration: Duration(seconds: 90),
);
setState(() {
if (fileTaken != null) {
this.files.add(fileTaken);
this.selected = true;
} else {
showError();
}
});
}
handleChooseFromGallery() async {
Navigator.pop(context);
File filePicked = await ImagePicker.pickVideo(
source: ImageSource.gallery,
maxDuration: Duration(seconds: 90),
);
print({'is file not null': filePicked != null});
setState(() {
if (filePicked != null) {
this.files.add(filePicked);
this.selected = true;
} else {
showError();
}
});
}
selectImage(parentContext) {
return showDialog(
context: parentContext,
builder: (context) {
return SimpleDialog(
title: Text("Seleccionar video"),
children: <Widget>[
SimpleDialogOption(
child: Text("Tomar video"),
onPressed: handleTakePhoto,
),
SimpleDialogOption(
child: Text("Video de la galería"),
onPressed: handleChooseFromGallery,
),
SimpleDialogOption(
child: Text("Cancelar"),
onPressed: () => Navigator.pop(context),
)
],
);
},
);
}
Future<String> uploadVideo(imageFile) async {
StorageUploadTask uploadTask = storageRef
.child(Provider.of<UserData>(context, listen: false).user.id)
.child(Provider.of<CourseData>(context, listen: false).course.uid)
.child(Provider.of<SemanaData>(context, listen: false).semana.uid)
.putFile(imageFile, StorageMetadata(contentType: 'video/mp4'));
StorageTaskSnapshot storageSnap = await uploadTask.onComplete;
String downloadUrl = await storageSnap.ref.getDownloadURL();
return downloadUrl;
}
createPostInFirestore({List<String> mediaUrl, String description}) {
postsRef
.document(Provider.of<UserData>(context, listen: false).user.id)
.collection("userPosts")
.document(Provider.of<CourseData>(context, listen: false).course.uid)
.setData({
"semana": Provider.of<SemanaData>(context, listen: false).semana.uid,
"postId": postId,
"ownerId": Provider.of<UserData>(context, listen: false).user.id,
"username": Provider.of<UserData>(context, listen: false).user.username,
"mediaUrl": mediaUrl,
"description": description,
"timestamp": timestamp,
"likes": {},
});
}
handleSubmit() async {
setState(() {
isUploading = true;
});
List<String> mediaUrlS = [];
for (File fileLoop in files) {
String mediaUrl = await uploadVideo(fileLoop);
mediaUrlS.add(mediaUrl);
}
createPostInFirestore(
mediaUrl: mediaUrlS,
description: captionController.text,
);
captionController.clear();
setState(() {
files = [];
isUploading = false;
postId = Uuid().v4();
selected = false;
});
}
Scaffold buildUploadForm() {
return Scaffold(
appBar: AppBar(
title: Text(
"Tu video",
style: TextStyle(color: Colors.black),
),
actions: [
FlatButton(
onPressed: files.length < 2 ? selectImage(context) : null,
child: Text(
'Seleccionar otro video',
),
),
FlatButton(
onPressed: isUploading ? null : () => handleSubmit(),
child: Text(
"Mandar",
),
),
],
),
body: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: files.length,
itemBuilder: (BuildContext context, int index) {
final File fileBuilder = files[index];
return Container(
height: 220.0,
width: MediaQuery.of(context).size.width * 0.8,
child: Center(
child: AspectRatio(
aspectRatio: 16 / 9,
child: Container(
child: ChewieListItem(
videoUrl: fileBuilder.path,
network: false,
file: fileBuilder,
),
),
),
),
);
}),
);
}
Widget buildNormalScreen () {
return Container(
child: GestureDetector(
onTap: () {
selectImage(context);
},
child: Container(
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
color: Theme.of(context).accentColor,
),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Subir videos',
style: TextStyle(
fontFamily: 'Comfortaa',
fontSize: 17.0,
color: Colors.white,
),
),
],
),
),
),
),
);
}
#override
Widget build(BuildContext context) {
return !selected
? buildNormalScreen()
: buildUploadForm();
}
}
In the function at the top, I also tried doing something like ImagePicker.pickVideo().then((file){...}) but it didn't work.
I also added <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> to my "android/app/src/main/AndroidManifest.xml" file.
I also tried adding android:requestLegacyExternalStorage="true" inside the <application> tag in my "android/app/src/main/AndroidManifest.xml" file, but then I get an error:
I don't know what I should be changing either in my code or in one of the files in the android folder, any help is deeply appreciated.
Thank you very much in advance
Put the condition in the same function.
handleChooseFromGallery() async {
Navigator.pop(context);
File filePicked = await ImagePicker.pickVideo(
source: ImageSource.gallery,
maxDuration: Duration(seconds: 90),
//This line always returns false
print({'is file not null': filePicked != null});
setState(() {
if (filePicked != null) {
this.files.add(filePicked);
this.selected = true;
} else {
showError();
}
});
}
);