Функция Firebase cloud неверно изменяет временные метки событий

#firebase #google-cloud-firestore #google-cloud-functions

#firebase #google-облако-firestore #google-cloud-функции

Вопрос:

мы создаем систему, в которой изменения в Firestore создают PubSub-сообщение, на которое могут воздействовать другие компоненты.

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

env.ts:

 import * as functions from 'firebase-functions';
import {handler} from '@handlers/rootCollection';

//noinspection JSUnusedGlobalSymbols
export const handlerFunction = functions.firestore
    .document('rootcollection/{documentID}')
    .onWrite(handler.process.bind(handler));
  

rootCollection.ts:

 import {DocumentSnapshot} from 'firebase-functions/lib/providers/firestore';
import {Change, EventContext} from 'firebase-functions';

interface MessageI extends Object {
    eventID: string;
    ref: string;
    beforeID: string | null;
    afterID: string | null;
    fcfReceived: number | null;
}

class WriteHandler {
    public name: string;

    public constructor(name: string) {
        this.name = name;
    }

    public async process(change: Change<DocumentSnapshot>, context: EventContext): MessageI {
        const afterExists = change.after.exists;
        const beforeExists = change.before.exists;
        const afterID = afterExists ? change.after.updateTime.toMillis().toString() : null;
        const beforeID = beforeExists ? change.before.updateTime.toMillis().toString() : null;

        return {
            'eventID': context.eventId,
            'ref': change.before.ref.path,
            'beforeID': beforeID,
            'afterID': afterID,
            'fcfReceived': Date.now()
        };
    }
}

export const itinerariesHandler = new WriteHandler(
    'rootCollectionHandler'
);
  

Теперь мы довольно удивлены, что данные правильно отражают состояния до и после, но временная метка, похоже, является after.timestamp.

Опубликовано сообщение 429345402459000 в теме. Сообщение:

 {
  "eventID":    "389fe158-115a-43ca-9fdd-ec9737af066f-0",
  "ref":        "collection/VMDcsHirbB2coyaXF5wZ",
  "beforeID":   "1552298315479",
  "afterID":    "1552298315479",
  "fcfReceived": 1552298315575,
}
  

Кажется нелогичным, что change.before.updateTime содержит время, когда было сделано изменение. Но я не могу найти явного упоминания в документации.

Предполагается ли такое поведение? Есть ли другой способ найти уникальный идентификатор для предыдущего состояния?

С уважением, Карстен

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

1. Я не уверен, что правильно понимаю. Как updateTime заполняется? Как объявляется и вызывается функция? Можете ли вы обновить свой вопрос, чтобы показать минимальную, но полную облачную функцию, которая воспроизводит проблему, и вызов на стороне клиента, который ее запускает?

2. Конечно. Я надеюсь, что редактирование поможет. Вызовы выполняются серверной частью java 8 через библиотеки firestore sdk с обычными операциями установки и обновления. Если что-то еще неясно, дайте мне знать.

3. Я спрашиваю у окружающих. На первый взгляд это звучит как ошибка.

Ответ №1:

firebaser здесь

Это ошибка в привязках Firestore для облачных функций. Это действительно устанавливает before.updateTime и after.updateTime в одно и то же значение.

Мы отправили внутреннюю ошибку, чтобы исправить это. Но нет временной шкалы, когда это исправление будет доступно.

До этого момента лучшее, что я могу придумать, это добавить lastUpdated поле к данным документа и подтвердить, что это текущая временная метка на стороне сервера в ваших правилах безопасности. Таким образом, вы можете получить before.data().lastUpdated и after.data().lastUpdated для выполнения сравнения. Это, по крайней мере, должно позволить вам реализовать поведение, пока проблема не будет устранена.