Flutter Firebase实时数据库.Streambuilder和listview.builder返回错误索引超出



我正在使用Flutter和Firebase构建订单应用程序。我使用实时数据库和流生成器来获取数据,并使用每次更新和listview.builder来描述它们。

当我显示数据时工作正常,但问题是当我试图在RTDB中扩展数据时,我得到了这个错误

引发了另一个异常:RangeError(index(:索引超出范围:索引应小于22:22。

我正试图在另一个页面上展开数据。对不起,如果我的问题有点垃圾,我是第一次问

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':''});
}

我正在更新此页面上的RTDB

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'));
}
}
}

这就是发生错误的地方

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",});
}

在获得所有数据后,它试图通过每次添加1来获得新数据,更改尝试在这里更改您的逻辑

最新更新