Reputation: 17173
I have a firebase app, when user uploads photo to storage, it triggers a generatethumbnail cloud function. All standard code, it worked fine, i deployed on Feb 24th 2019. Now when I Upload a photo, nothing happens. I look in storage and the photo is there, but when i look at the logs for firebase cloud functions, the generateThumbnail function hasn't been called. How can I debug / fix this? I was thinking of just redeploying my code, or perhaps upgrading my libraries etc in case there have been breaking changes?
Here's my code:
import * as functions from 'firebase-functions';
// import * as Storage from '@google-cloud/storage';
// const gcs = new Storage();
import * as admin from 'firebase-admin';
const gcs = admin.storage()
const firestore = admin.firestore();
import { tmpdir } from 'os';
import { join, dirname } from 'path';
import * as sharp from 'sharp';
import * as fs from 'fs-extra';
export const generateThumbs = functions.storage
.object()
.onFinalize(async object => {
const bucket = gcs.bucket(object.bucket);
const filePath = object.name;
const parts = filePath.split('/');
const fileName = parts.pop();
const propertyID = parts.pop();
// console.log(`got property id ${propertyID}`)
const bucketDir = dirname(filePath);
const workingDir = join(tmpdir(), 'thumbs');
const tmpFilePath = join(workingDir, fileName);
if (fileName.includes('thumb@') || !object.contentType.includes('image')) {
console.log('exiting function');
return false;
}
// 1. Ensure thumbnail dir exists
await fs.ensureDir(workingDir);
// 2. Download Source File
await bucket.file(filePath).download({
destination: tmpFilePath
});
// 3. Resize the images and define an array of upload promises
const sizes = [256];
let thumbLocation = '';
const uploadPromises = sizes.map(async size => {
const thumbName = `thumb@${size}_${fileName}`;
const thumbPath = join(workingDir, thumbName);
// Resize source image
await sharp(tmpFilePath)
.resize(256, 171)
.toFile(thumbPath);
thumbLocation = join(bucketDir, thumbName);
// Upload to GCS
return bucket.upload(thumbPath, {
destination: thumbLocation
});
});
// 4. Run the upload operations
await Promise.all(uploadPromises);
// 5. Cleanup remove the tmp/thumbs from the filesystem
await fs.remove(workingDir);
let photoURL = ''
const hour = 1000 * 60 * 60;
const year = hour * 24 * 365;
const EXP = Date.now() + year * 10;
await bucket.file(filePath).getSignedUrl({
action: 'read',
expires: EXP
}).then(signedUrls => {
photoURL = signedUrls[0];
});
let thumbURL = '';
await bucket.file(thumbLocation).getSignedUrl({
action: 'read',
expires: EXP
}).then(signedUrls => {
thumbURL = signedUrls[0];
});
if (!(photoURL && thumbURL)) {
return Promise.resolve('Error no thumbs');
}
const propertyRef = firestore.collection('properties').doc(propertyID);
return firestore.runTransaction(t => {
return t.get(propertyRef)
.then(doc => {
if (!doc.exists) {
console.log(`doc does not exist ${propertyID}`)
return;
}
let photos = doc.data().photos;
photos = photos || [];
photos.push({
big: photoURL,
small: thumbURL,
});
t.update(propertyRef, { photos: photos });
});
});
});
Upvotes: 0
Views: 1174
Reputation: 599011
All standard code, it worked fine, i deployed on Feb 24th 2019.
Until a month or so ago Cloud Functions would get deactivated by the system if they'd been inactive for 30 days or more. This behavior has since been changed, since it was quite unintuitive to most developers. But you will need to redeploy your Cloud Functions once more to opt in to the new behavior.
Upvotes: 1