Reputation: 17
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?
Upvotes: 0
Views: 1673
Reputation: 570
Try using FieldValue.arrayUnion([data]) this way in firebase doc
addToScoreLog({required int newLoggedScore, required String userIdF}) {
final data = {
"loggedScore": 20,
"createdAt": DateTime.now(), // this will be saved in TimeStamp Formate
};
//
_scoreDataBaseRef.doc('docID').update({
"scoresLog": FieldValue.arrayUnion([data])
}).whenComplete(() => log('ScoreDataBase Call: added To Logged Score'));
}
read more Here enter link description here
Upvotes: 0
Reputation: 9744
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));
Upvotes: 2