I'm currently working with FLutter and firebase. I'm trying to upload some data to the cloud firestore. So far so good. I have a problem when I'd like to append to a field a list. As mentioned before this field contains a list of values defined as below:
Map<String, Object> toDocument() {
Map customerAddress = Map();
Map orderCheckoutDetails = Map();
final DateTime now = DateTime.now();
final DateFormat formatter = DateFormat('dd-MM-yyyy');
final String formatted = formatter.format(now);
customerAddress['address'] = this.address;
customerAddress['city'] = this.city;
customerAddress['state'] = this.state;
customerAddress['zipCode'] = this.zipCode;
orderCheckoutDetails['checkoutOrderDate'] = formatted;
orderCheckoutDetails['customerAddress'] = customerAddress;
orderCheckoutDetails['customerName'] = '${this.nome!} ${this.cognome!}';
orderCheckoutDetails['customerPhone'] = this.numeroTelefono!;
orderCheckoutDetails['products'] = this.products!.map((product) => product.name).toList();
orderCheckoutDetails['subtotal'] = this.subtotal!;
orderCheckoutDetails['deliveryFee'] = this.deliveryFee!;
orderCheckoutDetails['total'] = this.total!;
List<Map<dynamic, dynamic>> orderList = [orderCheckoutDetails];
return {
'orderCheckoutDetails': orderList,
};
}
This is how it shows me the item on Firebase (which is correct). enter image description here
This is how I upload the document to Firebase.
@override
Future<void> addCheckout(Checkout checkout) async {
print(checkout.email!);
final docExists = await _checkIfUserCheckoutExists(checkout.email!);
print(docExists);
if (!docExists) {
return _checkoutCollection
.doc(checkout.email!)
.set(checkout.toDocument());
} else {
await _checkoutCollection.doc(checkout.email!).update({
"orderCheckoutDetails":
FieldValue.arrayUnion(checkout.toDocument() as List)
});
}
}
What I'd like to do is to append at the end of the document another element (the checkout element passed by parameter). How can I do that?
CodePudding user response:
Your can use set
with merge option in both cases (whether the document exists or not), it will create or update the document as needed. Plus your toDocument
method should return orderList
itself, not the map you are currently returning.
Try this:
Map<dynamic, dynamic> toDocument() {
Map customerAddress = Map();
Map<dynamic, dynamic> orderCheckoutDetails = Map();
final DateTime now = DateTime.now();
final DateFormat formatter = DateFormat('dd-MM-yyyy');
final String formatted = formatter.format(now);
customerAddress['address'] = this.address;
customerAddress['city'] = this.city;
customerAddress['state'] = this.state;
customerAddress['zipCode'] = this.zipCode;
orderCheckoutDetails['checkoutOrderDate'] = formatted;
orderCheckoutDetails['customerAddress'] = customerAddress;
orderCheckoutDetails['customerName'] = '${this.nome!} ${this.cognome!}';
orderCheckoutDetails['customerPhone'] = this.numeroTelefono!;
orderCheckoutDetails['products'] = this.products!.map((product) => product.name).toList();
orderCheckoutDetails['subtotal'] = this.subtotal!;
orderCheckoutDetails['deliveryFee'] = this.deliveryFee!;
orderCheckoutDetails['total'] = this.total!;
return orderCheckoutDetails;
}
And then create / insert your document like:
return _checkoutCollection
.doc(checkout.email!)
.set({
'orderCheckoutDetails' : FieldValue.arrayUnion([checkout.toDocument])
}, SetOptions(merge: true));