#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
для выполнения сравнения. Это, по крайней мере, должно позволить вам реализовать поведение, пока проблема не будет устранена.