正在努力使用flutter cloud Firestore同时更新多个文档



我已经在这段代码上挣扎了一段时间,我正在为一家商店开发一款POS应用程序,所以我的一个功能是该应用程序能够注册添加到购物车中的每一件商品,当销售时,我需要通过从我的云消防商店数据库中的每个商品数量字段中删除一个单位来更新这些商品,所以我所做的是,每次用户将商品添加到购物车中时,它都会将该文档的ID添加到字符串数组中,例如[4434343334343543434],然后在用户确认销售后,我希望它循环浏览每个文档,并通过从每个商品文档的时间-数量字段中删除数字1来更新该字段,我试着简单地创建一个包含firebase更新的for循环,但出现了错误,然后我尝试使用批处理写入来完成,显然,在处理多个文件时,这应该会有所帮助,问题是我一直得到错误

未处理的异常:错误状态:此批处理已提交,无法再更改

它甚至一次都不会更改更新字段中的值,这是我的代码,我不确定我在这里做错了什么,但我对此感到疯狂。如果你有一个替代方案来实现我想要做的事情,那将不胜感激,

WriteBatch batch = FirebaseFirestore.instance.batch();
//Create a batch
print(cart_numbers.toString());
Future update() async {
for (var i = 0; i < cart_numbers.length; i++) {
print('is iterator wooooooorking !!!!!' + i.toString());
FirebaseFirestore.instance.collection("items")
.doc(cart_numbers[i].toString()).get().then((value) {
print('==============================================' +
value.data().toString());
print('==============================================' +
value.data()['quantity'].toString());
int newer = value.data()['quantity'];
newer--;
print('newwwwwwwwwwwwwwwwwwwwwwwwerrrrrrrrrrrrr' + newer.toString());
batch.update(
//Give the ref of document.
FirebaseFirestore.instance.collection('items')
.doc(cart_numbers[i].toString()),
//And the data to add in it.
{
'quantity': newer
}
);
});
}
}
void start() async {
await update();
batch.commit();
}
start()

这是调试控制台

is iterator wooooooorking !!!!!0
I/flutter ( 3091): is iterator wooooooorking !!!!!1
I/flutter ( 3091): is iterator wooooooorking !!!!!2
E/EGL_adreno( 3091): tid 3281: eglSurfaceAttrib(1582): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer( 3091): Failed to set EGL_SWAP_BEHAVIOR on surface 0x81bff820, error=EGL_BAD_MATCH
I/flutter ( 3091): found data on cloudstore Instance of '_MapStream<QuerySnapshotPlatform, QuerySnapshot>'
I/flutter ( 3091): yessssssssssssssssssssssssssssssssssssssssssssssssssss
I/flutter ( 3091): yessssssssssssssssssssssssssssssssssssssssssssssssssss
I/flutter ( 3091): =============================================={name: bobo2012, quantity: 7, price: 5000, category: Antivirus Software, id: 2467046743, productid: 496184004787577}
I/flutter ( 3091): ==============================================7
I/flutter ( 3091): newwwwwwwwwwwwwwwwwwwwwwwwerrrrrrrrrrrrr6
E/flutter ( 3091): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Bad state: This batch has already been committed and can no longer be change    

错误我一直得到

E/flutter ( 4054): #0      int._throwFormatException (dart:core-patch/integers_patch.dart:131:5)
E/flutter ( 4054): #1      int._parseRadix (dart:core-patch/integers_patch.dart:157:16)
E/flutter ( 4054): #2      int._parse (dart:core-patch/integers_patch.dart:100:12)
E/flutter ( 4054): #3      int.parse (dart:core-patch/integers_patch.dart:63:12)
E/flutter ( 4054): #4      Home.update.<anonymous closure>.<anonymous closure>
package:weepay_pos/home.dart:53
E/flutter ( 4054): #5      List.forEach (dart:core-patch/growable_array.dart:302:8)
E/flutter ( 4054): #6      Home.update.<anonymous closure>
package:weepay_pos/home.dart:52
E/flutter ( 4054): #7      _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter ( 4054): #8      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4054): #9      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter ( 4054): #10     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter ( 4054): #11     Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter ( 4054): #12     Future._completeWithValue (dart:async/future_impl.dart:529:5)
E/flutter ( 4054): #13     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:40:15)
E/flutter ( 4054): #14     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:311:13)
E/flutter ( 4054): #15     Query.get (package:cloud_firestore/src/query.dart)
package:cloud_firestore/src/query.dart:1
E/flutter ( 4054): <asynchronous suspension>
E/flutter ( 4054): #16     Home.update
package:weepay_pos/home.dart:51
E/flutter ( 4054): #17     Home.build.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure>
package:weepay_pos/home.dart:1278
E/flutter ( 4054): #18     _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter ( 4054): #19     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4054): #20     _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter ( 4054): #21     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter ( 4054): #22     Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter ( 4054): #23     Future._completeWithValue (dart:async/future_impl.dart:529:5)
E/flutter ( 4054): #24     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:40:15)
E/flutter ( 4054): #25     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:311:13)
E/flutter ( 4054): #26     CollectionReference.add (package:cloud_firestore/src/collection_reference.dart)
package:cloud_firestore/src/collection_reference.dart:1
E/flutter ( 4054): #27     _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter ( 4054): #28     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4054): #29     _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter ( 4054): #30     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter ( 4054): #31     Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter ( 4054): #32     Future._completeWithValue (dart:async/future_impl.dart:529:5)
E/flutter ( 4054): #33     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:40:15)
E/flutter ( 4054): #34     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:311:13)
E/flutter ( 4054): #35     MethodChannelDocumentReference.set (package:cloud_firestore_platform_interface/src/method_channel/method_channel_document_reference.dart)
package:cloud_firestore_platform_interface/…/method_channel/method_channel_document_reference.dart:1
E/flutter ( 4054): #36     _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter ( 4054): #37     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4054): #38     _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter ( 4054): #39     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter ( 4054): #40     Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter ( 4054): #41     Future._completeWithValue (dart:async/future_impl.dart:529:5)
E/flutter ( 4054): #42     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:40:15)
E/flutter ( 4054): #43     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:311:13)
E/flutter ( 4054): #44     MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart)
package:flutter/…/services/platform_channel.dart:1
E/flutter ( 4054): #45     _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter ( 4054): #46     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4054): #47     _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter ( 4054): #48     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)

不需要实现for循环。只需获取所有商品,并使用forEach((函数检查商品是否在购物车内。如果是,请编辑数量字段。

Future update(List<int> cartNumbers) async {
WriteBatch batch = FirebaseFirestore.instance.batch();
// 1. Get all items
// 2. Iterate through each item
// 3. Parse each document ID
// 4. Check if cart_numers contains item
// 5. Change quantity
FirebaseFirestore.instance.collection("items").get().then((querySnapshot) {
querySnapshot.docs.forEach((document) {
try {
// Only if DocumentID has only numbers
if (cartNumbers.contains(int.parse(document.id))) {
batch.update(document.reference,
{"quantity": document.data()["quantity"] - 1});
}
} on FormatException catch (error) {
// If a document ID is unparsable. Example "lRt931gu83iukSSLwyei" is unparsable.
print("The document ${error.source} could not be parsed.");
return null;
}
});
return batch.commit();
});
}

试试这个例子:

class HomePage extends StatelessWidget {
// In this case, I manually added the items ids
final List<int> cartNumbers = [121212, 434343, 565656];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Items"),
actions: [
Center(
child: Padding(
padding: const EdgeInsets.only(right: 15),
child: Text("Quantity"),
))
],
),
body: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection("items").snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: [
Expanded(
child: ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data.docs[index].id),
trailing: Text(
snapshot.data.docs[index]["quantity"].toString()),
);
},
),
),
RaisedButton(
onPressed: () => update(cartNumbers),
child: Text("Update"),
),
],
);
} else {
return Center(child: CircularProgressIndicator());
}
},
));
}
}

最新更新