Firestore получает значение Field.increment после обновления без чтения данных документа - PullRequest
1 голос
/ 08 июля 2019

Есть ли способ получить обновленное значение поля документа, обновленного с помощью firestore.FieldValue.increment, не запрашивая документ?

var countersRef = db.collection('system').doc('counters');

await countersRef.update({
    nextOrderCode: firebase.firestore.FieldValue.increment(1)
});

// Get the updated nextOrderCode without asking for the document data?

Это связано не с расходами, а с надежностью.Например, если я хочу создать код, который увеличивается для каждого заказа, нет никакой гарантии, что, если >= 2 заказы произойдут в одно и то же время, будут иметь разные коды, если я прочту инкрементное значение сразу после разрешения обновления документа, потому что если>= 2 записи выполняются до первого чтения, тогда как минимум 2 документа будут иметь одинаковый код, даже если nextOrderCode будет иметь правильный шаг приращения.

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Это невозможно. Вам нужно будет прочитать документ после обновления, если вы хотите узнать значение.

Если вам нужно контролировать значение числа, чтобы оно не было недействительным, вам придется вместо этого использовать транзакцию, чтобы убедиться, что приращение не запишет недопустимое значение. FieldValue.increment() не будет хорошим выбором для этого случая.

0 голосов
/ 09 июля 2019

Мы можем сделать это с помощью Транзакции Firestore , как инкрементная обработка до Field.increment:

try {
  const orderCodesRef = admin.firestore().doc('system/counters/order/codes');
  let orderCode = null;
  await admin.firestore().runTransaction(async transaction => {
    const orderCodesDoc = await transaction.get(orderCodesRef);
    if(!orderCodesDoc.exists) {
      throw { reason: 'no-order-codes-doc' };
    }

    let { next } = orderCodesDoc.data();
    orderCode = next++;
    transaction.update(orderCodesRef, { next });
  });

  if(orderCode !== null) {
    newOrder.code = orderCode;
    const orderRef = await admin.firestore().collection('orders').add(newOrder);

    return success({ orderId: orderRef.id });
  } else {
    return fail('no-order-code-result');
  }
} catch(error) {
  console.error('commitOrder::ERROR', error);
  throw errors.CantWriteDatabase({ error });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...