Skip to content

Instantly share code, notes, and snippets.

@yamitzky
Created December 10, 2018 14:07
Show Gist options
  • Save yamitzky/a92169183d3b7d0d20afee6c1d872f77 to your computer and use it in GitHub Desktop.
Save yamitzky/a92169183d3b7d0d20afee6c1d872f77 to your computer and use it in GitHub Desktop.
Firebase Cloud Functions File Upload
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import { Storage } from '@google-cloud/storage'
import * as path from 'path'
import * as os from 'os'
import * as fs from 'fs'
import { spawn } from 'child-process-promise'
const gcs = new Storage({ keyFilename: path.resolve(__dirname, '..', 'service-account-credentials.json') })
admin.initializeApp()
export const convertImage = functions.runWith({ memory: '2GB' }).storage.object().onFinalize(async object => {
const filePath = object.name
if (!filePath) {
console.log(object.name, 'is null')
return
}
const [ , partyId, , rest ] = filePath.split(path.sep)
const fileName = path.basename(filePath)
if (rest) {
// ignore files in sub-dir
console.log(object.name, 'is a thumbnail.')
return
}
const bucket = gcs.bucket(object.bucket)
const file = bucket.file(filePath)
const db = admin.firestore()
const doc = await db.collection('parties').doc(partyId).collection('messages').doc()
await file.makePublic()
await doc.set({
imageURL: `https://storage.googleapis.com/${object.bucket}/${filePath}`,
createdAt: admin.firestore.FieldValue.serverTimestamp()
})
admin.storage().bucket(object.bucket)
console.log('Converting', filePath)
const tempFilePath = path.join(os.tmpdir(), fileName)
const outFilePath = path.join(os.tmpdir(), path.basename(fileName, path.extname(fileName)) + '.jpg')
await file.download({ destination: tempFilePath })
console.log('Downloaded', filePath, 'to', tempFilePath)
await spawn('convert', [tempFilePath, '-auto-orient', '-thumbnail', '800x800>', outFilePath])
console.log('Converted', tempFilePath, 'to', outFilePath)
const thumbFileName = `thumb/` + path.basename(outFilePath)
const thumbFilePath = path.join(path.dirname(filePath), thumbFileName)
const metadata = { contentType: object.contentType }
const [ uploaded ] = await bucket.upload(outFilePath, { destination: thumbFilePath, resumable: false, metadata })
console.log('Uploaded', outFilePath, 'to', thumbFilePath)
await uploaded.makePublic()
await doc.update({ thumbURL: `https://storage.googleapis.com/${uploaded.bucket.name}/${uploaded.name}` })
fs.unlinkSync(tempFilePath)
fs.unlinkSync(outFilePath)
})
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"main": "lib/index.js",
"dependencies": {
"@google-cloud/storage": "^2.2.0",
"child-process-promise": "^2.2.1",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.0.3"
},
"devDependencies": {
"tslint": "~5.8.0",
"typescript": "~3.1.4"
},
"private": true
}
{
"compilerOptions": {
"lib": ["es6"],
"module": "commonjs",
"noImplicitReturns": true,
"outDir": "lib",
"sourceMap": true,
"target": "es6"
},
"compileOnSave": true,
"include": [
"src"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment