3

Working with cloud firestore its always good to keep in mind about count of document read. I am working on an inventory app in which bill is getting generated for the list of products along with other details. Everything is working fine except the update of arraylist in the bill. I am able to insert the arraylist of product along with other details in the bill but i am not able to update the arraylist later. Whenever i try to insert more arraylist into the document, old arraylist get deleted. I dont understand how to insert more entries into that arraylist.

private void loadDatatoFirestore() {
        //product details entry
        final ArrayList<OrderedProductModel> newProductModel = new ArrayList<>();
        for (int i=0; i<productModelList.size(); i++){
            OrderedProductModel model = new OrderedProductModel(productModelList.get(i).getProductNumber(),
                    productModelList.get(i).getProductName(),
                    productModelList.get(i).getOrderedQuantity(),
                    productModelList.get(i).getSellingPrice());
            newProductModel.add(model);
        }

       BillModel insertBill = new BillModel(billNumber, partyName, date, totalPrice, BILL_STATUS, newProductModel);

        db.collection("mainCollection").document("BillDocument")
                .collection("BillCollection")
                .document(billNumber)
                .set(insertBill, SetOptions.merge())
                .addOnSuccessListener(new OnSuccessListener<Void>() {...}  

the above code is working fine.. but now i want to insert more entries into orderderProduct array. I am trying to solve it like this but compile time error occurs then. I have no idea how to update array here.

private void updateBill(String billNumber) {
      //here i am trying to insert dummy data 
        ArrayList<OrderedProductModel> testArray = new ArrayList<>();
        testArray.add(new OrderedProductModel("9999","testprod1",50,40));
        testArray.add(new OrderedProductModel("9911","testprod2",70,60));
        BillModel billtest = new BillModel(testArray);
        db.collection("mainCollection").document("BillDocument")
                .collection("BillCollection")
                .document(billNumber)
                .update(billtest,SetOptions.merge())
                .addOnSuccessListener(new OnSuccessListener<Void>() {....}

BillModel

public class BillModel {
    String billNumber;
    String partyName;
    String billingDate;
    float totalPrice;
    String status;
    ArrayList<OrderedProductModel> orderderProduct;

    public BillModel(ArrayList<OrderedProductModel> orderderProduct) {
        this.orderderProduct = orderderProduct;
    }

    public BillModel(String billNumber, String partyName, String billingDate, float totalPrice, String status, ArrayList<OrderedProductModel> orderderProduct) {
        this.billNumber = billNumber;
        this.partyName = partyName;
        this.billingDate = billingDate;
        this.totalPrice = totalPrice;
        this.status = status;
        this.orderderProduct = orderderProduct;
    }

OrderedProductModel

public class OrderedProductModel {
    private String productNumber;
    private String productName;
    private int orderedQuantity;
    private float sellingPrice;

    public OrderedProductModel(String productNumber, String productName, int orderedQuantity, float sellingPrice) {
        this.productNumber = productNumber;
        this.productName = productName;
        this.orderedQuantity = orderedQuantity;
        this.sellingPrice = sellingPrice;
    }

Attaching the image... firestore image
bill creation image

Amit Sen
  • 177
  • 2
  • 12

1 Answers1

5

If you want to update the contents of an array type in Firestore, you can't simply merge in a new array. A new field value will always entirely replace an old field value during a merge.

If you want to modify the contents of the array, you have to use the special FieldValue.arrayUnion() operation as the value for your field.

According to the API docs:

Returns a special value that can be used with set() or update() that tells the server to union the given elements with any array value that already exists on the server. Each specified element that doesn't already exist in the array will be added to the end. If the field being modified is not already an array it will be overwritten with an array containing exactly the specified elements.

This is described in more detail the documentation.

Unforunately, this is not compatible with the automatic field mapping that occurs with Java POJO objects, as you're using with BillModel. You'll have to convert your code to update the document with a Map type object instead, manually copying values into it for each of the BillModel fields you want to modify.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • thanks for the reply, I want to know is it possible that i can add more array list of java POJO objects into it . So that i can try my best. – Amit Sen Dec 11 '18 at 19:07
  • If you muse use a POJO, you will have to read the data out of the document first, make modifications to it in memory, then write it back out. If you just want to add items, it's more efficient to use FieldValue.arrayUnion(). – Doug Stevenson Dec 11 '18 at 19:09