Триггеры onCreate, onUpdate, onDelete в Firebase Cloud Functions

В этой статье рассмотрим новые типы триггеров Firebase, которые были добавлены в firebase-functions 0.5.9

В первой версий Realtime database triggers был доступен только один триггер для всех типов изменений данных, он назывался onWrite(). И вся работа по определению события ложилась на плечи разработчика. Например, представите, вам нужно обрабатывать только создание новой записи, раньше это делалось так:

Обработка события onWrite
 exports.handleNewComment = functions.database
     .ref("/comments/{commentId}").onWrite(event => {
         const dataSnaphot = event.data; // 
         if (dataSnaphot.exists() !dataSnaphot.previous.exists()) { //проверка 
             // Если новый комментарий отправляем пуш
         }
     })

Такой подход не эффективен так как большинстве случаев функция вызывается, но не делает ничего полезного, а каждый вызов стоит денег. Но теперь в библиотеке firebase-functions версии 0.5.9, доступно три новых триггера базы даних: onCreate (), onUpdate () и onDelete (). Теперь обработку создания можно сделать так:

 
exports.handleNewComment = functions.database
 .ref("/comments/{commentId}").onCreate(event => {
 var sender= new FcmSender(); // Можно не проверять, сразу отсылаем пуш
 sender.send(push);
})
Решения проблемы бесконечных циклов onWrite () и onUpdate ()

Если раньше вы использовали триггер onWrite () чтобы добавить или изменить данные в одном месте, вы должны били заметить, что изменения что вы сделали вовремя onWrite () приведет к повторному вызову этого же триггера.
Например, эта функция обновляет поле updatedAt, когда комментарий был изменён:

 
exports.lastUpdate = functions.database
    .ref("/comments/{commentId}").onWrite(event => {
        const comment = event.data.val()
        comment.updatedAt = Date.now()
        return event.data.adminRef.set(comment)
    })

Вроде бы, все правильно, но мы упустили что-то важное. Так как функция пишет в то же место, по которому сработал триггер, она запустит бесконечный цикл таких изменений
Оказывается, что в onUpdate() тоже может быть такая проблема. Одно из возможных решений проверять текущее значение updatedAt и на сколько оно меньше текущей даты, если больше чем 30 секунд тогда обновляем.

 
exports.lastUpdate = functions.database
    .ref("/comments/{commentId}").onUpdate(event => {
        const comment = event.data.val()
        const now = Date.now()
        if (comment.updatedAt > now - (30 * 1000)) {
            return
        }
        comment.msg.updatedAt = now
        return event.data.adminRef.set(comment)
    })
Заключение

Главным преимуществом такого подхода есть то что не нужно руками определять тип события. Также можно сократить количество ненужных вызовов cloud functions.

 

nazarmsx

 

Leave a Reply

Your email address will not be published. Required fields are marked *