Tuesday 6 June 2017

Firebase: Create FIFO Inventory to get value

I have been stuck with this problem for a month.

I've been trying to use firebase to create a FIFO Inventory. I am using firebase cloud function to update the FIFO inventory. However if I stress test the following code just 10 times with for loop for both insert (push) and remove (pop), it breaks because of the concurrent update.

Does anyone have another solution for this?

Insert FIFO/PUSH:

let fifoRef = admin.database().ref('fifo/' + item.itemId + '/').push();
let fifo = {
    price: data.items[uniqueId].price,
    in: data.items[uniqueId].quantity,
    quantity: data.items[uniqueId].quantity,
}
fifoRef.set(fifo);

Get FIFO Value/POP (Here I simply update the quantity for POP):

// get fifo
let fifoReference = 'fifo/' + item.itemId;
let fifoRef = admin.database().ref(fifoReference);
fifoRef.once('value').then(currentData => {
  let fifo = currentData.val();

  for (let key in fifo) {
    let val = fifo[key];

    if (val.quantity > 0) {
    // get fifo quantity
    let fifoQuantityRef = admin.database().ref(fifoReference + '/' + key + '/quantity/');

    // get local cache value
    let fifoQuantityListener = fifoQuantityRef.on('value', () => {                                      
      // transaction start
      fifoQuantityRef.transaction(function (quantity) {
        if (quantity) {
          if (quantity > 0 && quantitySubtotal > 0) {

            if (quantity >= quantitySubtotal) {
              // minus inventory amount
              let amount = calculator(quantitySubtotal + "*" + val.price);

              quantity = calculator(quantity + "-" + quantitySubtotal);
              quantitySubtotal = 0;

              // update quantity
              return quantity;
            } else {
              let amount = calculator(quantity + "*" + val.price);

              quantitySubtotal = calculator(quantitySubtotal + "-" + quantity);
              return 0;
            }
          }
        }
        return quantity;
      }, (error, committed, result) => {
        fifoQuantityRef.off('value', fifoQuantityListener);
    }, true);
  });

Brainstorming: I just need Insight on how to get the VALUE using FIFO. From my understanding Firebase is best used to insert and remove not with transaction. But if I am using only insert and remove, how to create a FIFO? If I create FIFO with the quantity of 1, the data stored will be too large.

I did try to use Google Datastore, however datastore persistence is extremely slow (over 2 seconds for writing). Which is not possible to be used with firebase which have persistence of less than 1 second. The problem arise when PUSH and POP is done within 1 seconds, datastore insert is not persisted yet.

Any other brainstorming ideas?



via Fendy Jong

No comments:

Post a Comment