UNPKG

firebase-functions

Version:
79 lines (77 loc) • 3.55 kB
import { error, warn } from "../../logger/index.mjs"; import { getApp } from "../app.mjs"; import { dateToTimestampProto } from "../utilities/encoder.mjs"; import * as firestore from "firebase-admin/firestore"; import { google } from "../../../../protos/compiledFirestore.mjs"; //#region src/common/providers/firestore.ts /** static-complied protobufs */ const DocumentEventData = google.events.cloud.firestore.v1.DocumentEventData; /** * Helper to construct a value protobuf or return the document resource path. * * @param data - The Firestore event data payload. * @param resource - The slash-separated document resource path (e.g. * `projects/{project}/databases/{database}/documents/{document_path}`). This is used as the fallback * when the document name or data is not present in the payload (e.g., for non-existent/deleted snapshots). * @param valueFieldName - The key in `data` to extract the document fields from ('value' or 'oldValue'). * @returns A protobuf-like object representing the document, or the fallback resource path string. * @hidden */ function _getValueProto(data, resource, valueFieldName) { const value = data?.[valueFieldName]; if (typeof value === "undefined" || value === null || typeof value === "object" && !Object.keys(value).length) { return resource; } const proto = { fields: value?.fields || {}, createTime: dateToTimestampProto(value?.createTime), updateTime: dateToTimestampProto(value?.updateTime), name: value?.name || resource }; return proto; } /** @internal */ function createSnapshotFromProtobuf(data, path, databaseId) { const firestoreInstance = firestore.getFirestore(getApp(), databaseId); try { const dataBuffer = Buffer.from(data); const firestoreDecoded = DocumentEventData.decode(dataBuffer); return firestoreInstance.snapshot_(firestoreDecoded.value || path, null, "protobufJS"); } catch (err) { error("Failed to decode protobuf and create a snapshot."); throw err; } } /** @internal */ function createBeforeSnapshotFromProtobuf(data, path, databaseId) { const firestoreInstance = firestore.getFirestore(getApp(), databaseId); try { const dataBuffer = Buffer.from(data); const firestoreDecoded = DocumentEventData.decode(dataBuffer); return firestoreInstance.snapshot_(firestoreDecoded.oldValue || path, null, "protobufJS"); } catch (err) { error("Failed to decode protobuf and create a before snapshot."); throw err; } } /** @internal */ function createSnapshotFromJson(data, path, createTime, updateTime, databaseId) { const firestoreInstance = databaseId ? firestore.getFirestore(getApp(), databaseId) : firestore.getFirestore(getApp()); const valueProto = _getValueProto(data, path, "value"); let timeString = createTime || updateTime; if (!timeString) { warn("Snapshot has no readTime. Using now()"); timeString = new Date().toISOString(); } const readTime = dateToTimestampProto(timeString); return firestoreInstance.snapshot_(valueProto, readTime, "json"); } /** @internal */ function createBeforeSnapshotFromJson(data, path, createTime, updateTime, databaseId) { const firestoreInstance = databaseId ? firestore.getFirestore(getApp(), databaseId) : firestore.getFirestore(getApp()); const oldValueProto = _getValueProto(data, path, "oldValue"); const oldReadTime = dateToTimestampProto(createTime || updateTime); return firestoreInstance.snapshot_(oldValueProto, oldReadTime, "json"); } //#endregion export { createBeforeSnapshotFromJson, createBeforeSnapshotFromProtobuf, createSnapshotFromJson, createSnapshotFromProtobuf };