Как обрабатывать бесконечные циклы облачных функций Firebase?

# #node.js #firebase-realtime-database #google-cloud-functions

Вопрос:

У меня есть облачные функции Firebase, которые запускаются обновлением некоторых данных в базе данных Firebase в реальном времени. Когда данные обновляются, я хочу прочитать данные, выполнить некоторые вычисления с этими данными, а затем сохранить результаты вычислений обратно в базу данных реального времени. Это выглядит так:

 exports.onUpdate = functions.database.ref("/some/path").onUpdate((change) => {
    const values = change.after.val();
    const newValues = performCalculations(value);
    return change.after.ref.update(newValues);
});
 

Меня беспокоит то, что это может создать неопределенный цикл обновлений. Я видел заметку на триггерах Cloud Firestore, в которой говорится:

«Каждый раз, когда вы пишете в тот же документ, который запустил функцию, вы рискуете создать бесконечный цикл. Будьте осторожны и убедитесь, что вы безопасно выходите из функции, когда никаких изменений не требуется».

Итак, мой первый вопрос: относится ли эта же проблема к базе данных Firebase в реальном времени?

Если да, то каков наилучший способ предотвратить бесконечное зацикливание? Должен ли я сравнивать снимки до/после, пары ключ/значение и т. Д.?

Моя идея до сих пор:

 exports.onUpdate = functions.database.ref("/some/path").onUpdate((change) => {

    // Get old values
    const beforeValues = change.before.val();

    // Get current values
    const afterValues = change.after.val();

    // Something like this???
    if (beforeValues === afterValues) return null;
    
    const newValues = performCalculations(afterValues);
    return change.after.ref.update(newValues);
});
 

Спасибо

Ответ №1:

Относится ли та же проблема к базе данных Firebase в реальном времени?

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

Чтобы предотвратить бесконечный цикл, вы должны определить его состояние в коде. Ты можешь:

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

Любой из них может работать, и какой из них использовать, зависит от вашего варианта использования. Ваш if (beforeValues === afterValues) return null подход является формой второго подхода и действительно может сработать, но это зависит от деталей данных, которыми вы не поделились.