Skip to content

Commit 7218557

Browse files
thatfiredevlaurenzlong
authored andcommitted
feat(storage-resize-images): copy metadata to resized image (#42)
1 parent 367a9ba commit 7218557

File tree

6 files changed

+46
-16
lines changed

6 files changed

+46
-16
lines changed

storage-resize-images/POSTINSTALL.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,24 @@ You can test out this extension right away:
1212

1313
### Using the extension
1414

15+
You can upload images using the [Cloud Storage for Firebase SDK](https://firebase.google.com/docs/storage/) for your platform (iOS, Android, or Web). Alternatively, you can upload images directly in the Firebase console's Storage dashboard.
16+
1517
When you upload an image file to `${param:IMG_BUCKET}`, this extension:
1618

1719
- Creates resized image(s) with your specfied dimensions.
18-
- Stores the resized image(s) in the bucket `${param:IMG_BUCKET}` (and, if configured, under the path `${param:RESIZED_IMAGES_PATH}`).
1920
- Names resized image(s) using the same name as the original uploaded image, but suffixed with the specified width and height.
21+
- Stores the resized image(s) in the bucket `${param:IMG_BUCKET}` (and, if configured, under the path `${param:RESIZED_IMAGES_PATH}`).
2022

21-
You can upload images using the [Cloud Storage for Firebase SDK](https://firebase.google.com/docs/storage/) for your platform (iOS, Android, or Web). Alternatively, you can upload images directly in the Firebase console's Storage dashboard.
23+
The extension also copies the following metadata, if present, from the original image to the resized image(s):
24+
25+
- [`Cache-Control`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control)
26+
- [`Content-Disposition`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Disposition)
27+
- [`Content-Encoding`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Encoding)
28+
- [`Content-Language`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Language)
29+
- [`Content-Type`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Type)
30+
- [user-provided metadata](https://cloud.google.com/storage/docs/metadata#custom-metadata) (except Firebase storage download tokens)
31+
32+
Note that if you configured the `Cache-Control header for resized images` param, the specified value will overwrite the value copied from the original image. Learn more about image metadata in the [Cloud Storage documentation](https://firebase.google.com/docs/storage/).
2233

2334
### Monitoring
2435

storage-resize-images/PREINSTALL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ Use this extension to create resized versions of an image uploaded to a Cloud St
33
When you upload an image file to your specified Cloud Storage bucket, this extension:
44

55
- Creates a resized image with your specified dimensions.
6-
- Stores the resized image in the same Storage bucket as the original uploaded image.
76
- Names the resized image using the same name as the original uploaded image, but suffixed with your specified width and height.
7+
- Stores the resized image in the same Storage bucket as the original uploaded image.
88

99
You can even configure the extension to create resized images of different dimensions for each original image upload. For example, you might want images that are 200x200, 400x400, and 680x680 - this extension can create these three resized images then store them in your bucket.
1010

11-
Another optional feature of this extension is to specify a [`Cache-Control` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) for your resized image files.
11+
The extension automatically copies the following metadata, if present, from the original image to the resized image(s): `Cache-Control`, `Content-Disposition`, `Content-Encoding`, `Content-Language`, `Content-Type`, and user-provided metadata (except Firebase storage download tokens). Note that you can optionally configure the extension to overwrite the [`Cache-Control`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control) value for the resized image(s).
1212

1313
#### Detailed configuration information
1414

storage-resize-images/extension.yaml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,10 @@ params:
144144
- param: CACHE_CONTROL_HEADER
145145
label: Cache-Control header for resized images
146146
description: >
147-
Do you want to specify a `Cache-Control` header for the resized image
148-
files? Learn more about
149-
[`Cache-Control` headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control).
150-
If you prefer not to use a `Cache-Control` header, leave this field empty.
147+
This extension automatically copies any `Cache-Control` metadata from the original image
148+
to the resized images. For the resized images, do you want to overwrite this copied
149+
`Cache-Control` metadata or add `Cache-Control` metadata? Learn more about
150+
[`Cache-Control` headers](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control).
151+
If you prefer not to overwrite or add `Cache-Control` metadata, leave this field empty.
151152
example: max-age=86400
152153
required: false

storage-resize-images/functions/lib/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ exports.default = {
2020
cacheControlHeader: process.env.CACHE_CONTROL_HEADER,
2121
imageSizes: process.env.IMG_SIZES.split(","),
2222
resizedImagesPath: process.env.RESIZED_IMAGES_PATH,
23-
deleteOriginalFile: process.env.DELETE_ORIGINAL_FILE,
23+
deleteOriginalFile: process.env.DELETE_ORIGINAL_FILE === "true",
2424
};

storage-resize-images/functions/lib/index.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ exports.generateResizedImage = functions.storage.object().onFinalize((object) =>
5858
const fileName = path.basename(filePath);
5959
const fileExtension = path.extname(filePath);
6060
const fileNameWithoutExtension = fileName.slice(0, -fileExtension.length);
61+
const objectMetadata = object;
6162
let originalFile;
6263
let remoteFile;
6364
try {
@@ -84,6 +85,7 @@ exports.generateResizedImage = functions.storage.object().onFinalize((object) =>
8485
fileExtension,
8586
contentType,
8687
size,
88+
objectMetadata: objectMetadata,
8789
}));
8890
});
8991
const results = yield Promise.all(tasks);
@@ -118,7 +120,7 @@ exports.generateResizedImage = functions.storage.object().onFinalize((object) =>
118120
}
119121
}
120122
}));
121-
const resizeImage = ({ bucket, originalFile, fileDir, fileNameWithoutExtension, fileExtension, contentType, size, }) => __awaiter(this, void 0, void 0, function* () {
123+
const resizeImage = ({ bucket, originalFile, fileDir, fileNameWithoutExtension, fileExtension, contentType, size, objectMetadata, }) => __awaiter(this, void 0, void 0, function* () {
122124
const resizedFileName = `${fileNameWithoutExtension}_${size}${fileExtension}`;
123125
// Path where resized image will be uploaded to in Storage.
124126
const resizedFilePath = path.normalize(config_1.default.resizedImagesPath
@@ -129,14 +131,20 @@ const resizeImage = ({ bucket, originalFile, fileDir, fileNameWithoutExtension,
129131
resizedFile = path.join(os.tmpdir(), resizedFileName);
130132
// Cloud Storage files.
131133
const metadata = {
134+
contentDisposition: objectMetadata.contentDisposition,
135+
contentEncoding: objectMetadata.contentEncoding,
136+
contentLanguage: objectMetadata.contentLanguage,
132137
contentType: contentType,
133-
metadata: {
134-
resizedImage: "true",
135-
},
138+
metadata: objectMetadata.metadata,
136139
};
140+
metadata.metadata.resizedImage = true;
137141
if (config_1.default.cacheControlHeader) {
138142
metadata.cacheControl = config_1.default.cacheControlHeader;
139143
}
144+
else {
145+
metadata.cacheControl = objectMetadata.cacheControl;
146+
}
147+
delete metadata.metadata.firebaseStorageDownloadTokens;
140148
// Generate a resized image using ImageMagick.
141149
logs.imageResizing(resizedFile, size);
142150
yield child_process_promise_1.spawn("convert", [originalFile, "-resize", `${size}>`, resizedFile], {

storage-resize-images/functions/src/index.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import * as path from "path";
2626
import config from "./config";
2727
import * as logs from "./logs";
2828
import * as validators from "./validators";
29+
import { ObjectMetadata } from "firebase-functions/lib/providers/storage";
2930

3031
interface ResizedImageResult {
3132
size: string;
@@ -63,6 +64,7 @@ export const generateResizedImage = functions.storage.object().onFinalize(
6364
const fileName = path.basename(filePath);
6465
const fileExtension = path.extname(filePath);
6566
const fileNameWithoutExtension = fileName.slice(0, -fileExtension.length);
67+
const objectMetadata = object;
6668

6769
let originalFile;
6870
let remoteFile;
@@ -94,6 +96,7 @@ export const generateResizedImage = functions.storage.object().onFinalize(
9496
fileExtension,
9597
contentType,
9698
size,
99+
objectMetadata: objectMetadata,
97100
})
98101
);
99102
});
@@ -138,6 +141,7 @@ const resizeImage = async ({
138141
fileExtension,
139142
contentType,
140143
size,
144+
objectMetadata,
141145
}: {
142146
bucket: Bucket;
143147
originalFile: string;
@@ -146,6 +150,7 @@ const resizeImage = async ({
146150
fileExtension: string;
147151
contentType: string;
148152
size: string;
153+
objectMetadata: ObjectMetadata;
149154
}): Promise<ResizedImageResult> => {
150155
const resizedFileName = `${fileNameWithoutExtension}_${size}${fileExtension}`;
151156
// Path where resized image will be uploaded to in Storage.
@@ -161,14 +166,19 @@ const resizeImage = async ({
161166

162167
// Cloud Storage files.
163168
const metadata: any = {
169+
contentDisposition: objectMetadata.contentDisposition,
170+
contentEncoding: objectMetadata.contentEncoding,
171+
contentLanguage: objectMetadata.contentLanguage,
164172
contentType: contentType,
165-
metadata: {
166-
resizedImage: "true",
167-
},
173+
metadata: objectMetadata.metadata,
168174
};
175+
metadata.metadata.resizedImage = true;
169176
if (config.cacheControlHeader) {
170177
metadata.cacheControl = config.cacheControlHeader;
178+
} else {
179+
metadata.cacheControl = objectMetadata.cacheControl;
171180
}
181+
delete metadata.metadata.firebaseStorageDownloadTokens;
172182

173183
// Generate a resized image using ImageMagick.
174184
logs.imageResizing(resizedFile, size);

0 commit comments

Comments
 (0)