diff --git a/functions/src/scripts/set-avatar-cache-headers.ts b/functions/src/scripts/set-avatar-cache-headers.ts new file mode 100644 index 00000000..676ec62d --- /dev/null +++ b/functions/src/scripts/set-avatar-cache-headers.ts @@ -0,0 +1,27 @@ +import { initAdmin } from './script-init' +import { log } from '../utils' + +const app = initAdmin() +const ONE_YEAR_SECS = 60 * 60 * 24 * 365 +const AVATAR_EXTENSION_RE = /\.(gif|tiff|jpe?g|png|webp)$/i + +const processAvatars = async () => { + const storage = app.storage() + const bucket = storage.bucket(`${app.options.projectId}.appspot.com`) + const [files] = await bucket.getFiles({ prefix: 'user-images' }) + log(`${files.length} avatar images to process.`) + for (const file of files) { + if (AVATAR_EXTENSION_RE.test(file.name)) { + log(`Updating metadata for ${file.name}.`) + await file.setMetadata({ + cacheControl: `public, max-age=${ONE_YEAR_SECS}`, + }) + } else { + log(`Skipping ${file.name} because it probably isn't an avatar.`) + } + } +} + +if (require.main === module) { + processAvatars().catch((e) => console.error(e)) +} diff --git a/web/lib/firebase/storage.ts b/web/lib/firebase/storage.ts index fcf4422d..3acfbae9 100644 --- a/web/lib/firebase/storage.ts +++ b/web/lib/firebase/storage.ts @@ -3,6 +3,8 @@ import imageCompression from 'browser-image-compression' import { nanoid } from 'nanoid' import { storage } from './init' +const ONE_YEAR_SECS = 60 * 60 * 24 * 365 + export const uploadImage = async ( username: string, file: File, @@ -24,7 +26,9 @@ export const uploadImage = async ( }) } - const uploadTask = uploadBytesResumable(storageRef, file) + const uploadTask = uploadBytesResumable(storageRef, file, { + cacheControl: `public, max-age=${ONE_YEAR_SECS}`, + }) let resolvePromise: (url: string) => void let rejectPromise: (reason?: any) => void