Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update sharp, remove deprecated max fn call, retrieve image urls and … #730

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Update sharp, remove deprecated max fn call, retrieve image urls and …
…save to firebase rtdb
  • Loading branch information
alxvallejo committed May 28, 2020
commit a19258b331cc29a9c781b4d3f69ee28ecd27c38e
99 changes: 67 additions & 32 deletions image-sharp/functions/index.js
Original file line number Diff line number Diff line change
@@ -16,9 +16,12 @@
'use strict';

const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
const { Storage } = require('@google-cloud/storage');
const gcs = new Storage();
const path = require('path');
const sharp = require('sharp');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const THUMB_MAX_WIDTH = 200;
const THUMB_MAX_HEIGHT = 200;
@@ -28,42 +31,74 @@ const THUMB_MAX_HEIGHT = 200;
* Sharp.
*/
exports.generateThumbnail = functions.storage.object().onFinalize((object) => {
const fileBucket = object.bucket; // The Storage bucket that contains the file.
const filePath = object.name; // File path in the bucket.
const contentType = object.contentType; // File content type.
const fileBucket = object.bucket; // The Storage bucket that contains the file.
const filePath = object.name; // File path in the bucket.
const contentType = object.contentType; // File content type.

// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith('image/')) {
console.log('This is not an image.');
return null;
}
// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith('image/')) {
console.log('This is not an image.');
return null;
}

// Get the file name.
const fileName = path.basename(filePath);
// Exit if the image is already a thumbnail.
if (fileName.startsWith('thumb_')) {
console.log('Already a Thumbnail.');
return null;
}
// Get the file name.
const fileName = path.basename(filePath);
// Exit if the image is already a thumbnail.
if (fileName.startsWith('thumb_')) {
console.log('Already a Thumbnail.');
return null;
}

// Download file from bucket.
const bucket = gcs.bucket(fileBucket);
// Download file from bucket.
const bucket = gcs.bucket(fileBucket);

const metadata = {
contentType: contentType,
};
// We add a 'thumb_' prefix to thumbnails file name. That's where we'll upload the thumbnail.
const thumbFileName = `thumb_${fileName}`;
const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);
// Create write stream for uploading thumbnail
const thumbnailUploadStream = bucket.file(thumbFilePath).createWriteStream({metadata});
const metadata = {
contentType: contentType,
};
// We add a 'thumb_' prefix to thumbnails file name. That's where we'll upload the thumbnail.
const thumbFileName = `thumb_${fileName}`;
const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);
// Create write stream for uploading thumbnail
const thumbnailUploadStream = bucket.file(thumbFilePath).createWriteStream({ metadata });

// Create Sharp pipeline for resizing the image and use pipe to read from bucket read stream
const pipeline = sharp();
pipeline.resize(THUMB_MAX_WIDTH, THUMB_MAX_HEIGHT).max().pipe(thumbnailUploadStream);
// Create Sharp pipeline for resizing the image and use pipe to read from bucket read stream
const pipeline = sharp();
pipeline.rotate().resize(THUMB_MAX_WIDTH, THUMB_MAX_HEIGHT).pipe(thumbnailUploadStream);

bucket.file(filePath).createReadStream().pipe(pipeline);
bucket.file(filePath).createReadStream().pipe(pipeline);

return new Promise((resolve, reject) =>
thumbnailUploadStream.on('finish', resolve).on('error', reject));
const saveToDatabase = async () => {
const fileDir = path.dirname(filePath);
let nameParts = fileDir.split('/');
let userId;
// Get the user id from the filePath
if (nameParts[0] === 'profile_photos') {
userId = nameParts[1];
}
// Save the Signed URLs for the thumbnail and original image to the user profile.
const config = {
action: 'read',
expires: '03-01-2500',
};
const thumbFile = bucket.file(thumbFilePath);
const file = bucket.file(filePath);
const results = await Promise.all([thumbFile.getSignedUrl(config), file.getSignedUrl(config)]);
console.log('Got Signed URLs.');
const thumbResult = results[0];
const originalResult = results[1];
const thumbFileUrl = thumbResult[0];
const fileUrl = originalResult[0];
// Add the URLs to the Database
await admin.database().ref(`users/${userId}/profile/photo`).set({ path: fileUrl, thumbnail: thumbFileUrl });
console.log('Thumbnail URLs saved to database.');
};

return new Promise((resolve, reject) =>
thumbnailUploadStream
.on('finish', () => {
saveToDatabase();
resolve;
})
.on('error', reject)
);
});
48 changes: 24 additions & 24 deletions image-sharp/functions/package.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{
"name": "generate-thumbnail-sharp-functions",
"description": "Generate Thumbnail with Sharp Firebase Functions sample",
"dependencies": {
"@google-cloud/storage": "^4.3.1",
"sharp": "^0.24.1",
"firebase-admin": "~8.9.2",
"firebase-functions": "^3.3.0"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint-plugin-promise": "^4.2.1"
},
"scripts": {
"lint": "./node_modules/.bin/eslint --max-warnings=0 .",
"serve": "firebase serve --only functions",
"shell": "firebase experimental:functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"private": true
"name": "generate-thumbnail-sharp-functions",
"description": "Generate Thumbnail with Sharp Firebase Functions sample",
"dependencies": {
"@google-cloud/storage": "^4.3.1",
"sharp": "^0.25.3",
"firebase-admin": "~8.9.2",
"firebase-functions": "^3.3.0"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint-plugin-promise": "^4.2.1"
},
"scripts": {
"lint": "./node_modules/.bin/eslint --max-warnings=0 .",
"serve": "firebase serve --only functions",
"shell": "firebase experimental:functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"private": true
}