senna
senna

Reputation: 17

Append element to a list flutter firebase

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

Answers (2)

Sumit
Sumit

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

enter image description here

enter image description here

read more Here enter link description here

Upvotes: 0

Peter Koltai
Peter Koltai

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

Related Questions