Запустить пакет или транзакцию в облачном Firestore onCreate trigger

#javascript #node.js #firebase #google-cloud-firestore #google-cloud-functions

#javascript #node.js #firebase #google-cloud-firestore #google-cloud-функции

Вопрос:

Давайте представим, что в firestore у меня есть коллекция документов поставщика :

 vendors : {
  vendor1: {
    id: "vendor1",
    name: "John",
    shopId: "shop1"
  },
  vendor2: {
    id: "vendor2",
    name: "Mary",
    shopId: "shop2"
  }
}
  

И коллекция документов магазина :

 shops : {
  shop1: {
    id: "shop1",
    name: "My Super shop - City A",
    vendors : {
      vendor1: {
        id: "vendor1",
        name: "John"
  },
  shop2: {
    id: "shop2",
    name: "My Super shop - City B",
    vendors : {
      vendor2: {
        id: "vendor2",
        name: "Mary"
  }
}
  

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

Сегодня то, что я делаю, это :

 exports.updatesOnCreateVendor = functions
  .firestore.document("vendors/{vendorId}")
  .onCreate(async snapshot => {
    const vendor = snapshot.data();

    const { shopId } = vendor;

    const shopRef = db.collection("shops").doc(shopId);

    const shopAfter = {
      vendors: {}
    };

    shopAfter.vendors[vendorId] = { ...vendor };

    const batch = db.batch();

    batch.set(shopRef, shopAfter, { merge: true });

    return batch
           .commit()
           .then(console.log)
           .catch(console.error);
  });
  

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

Итак, я хотел бы знать, рекомендуется ли использовать пакет / транзакцию подобным образом для триггеров облачной функции?

Если я проведу рефакторинг этого и заменю пакетный процесс простым использованием shopRef.set(shopAfter, { merge: true }) , и если облачная функция не удалась, что произойдет? (Я думаю, что потеряю свою копию: p)

Спасибо за время, потраченное на то, чтобы помочь мне лучше понять Firebase 🙂

Комментарии:

1. Я не уверен, что понимаю, в чем здесь ваша проблема. Всегда есть вероятность, что вызов функции может завершиться неудачей. Также есть вероятность, что он будет повторен, если его статус не вернет его к корректным облачным функциям. Если вы обеспокоены тем, что что-то может завершиться ошибкой, и вы не хотите потерять событие, которое запустило функцию, вам действительно нужно включить повторные попытки для этой функции и правильно обработать эти попытки.

2. Извините, если это сбивает с толку. Я просто хочу знать, не слишком ли сложно использовать пакет в этой ситуации: убедитесь, что при создании «триггера» действительно записываются мои данные, даже если что-то вызывает сбой облачной функции (тайм-аут, проблема с сетью и т.д.). Насколько я понимаю документацию, пакет, похоже, выполняется независимо. Верно ли думать, что независимо от того, какая функция запускает пакет, фиксация будет продолжаться в фоновом режиме, даже если функция завершится?

Ответ №1:

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

Комментарии:

1. Допустим, пакет создает несколько документов в коллекции, за которыми у вас следит триггер onCreate. Запускает ли пакет функцию onCreate столько раз, сколько было создано документов, или он запускает ее только один раз? В какие центры сертификации вы можете получить недавно добавленные документы?