Notes

Cloud Functions

Functions samples

Mount an Express app

1
const functions = require('firebase-functions');
2
const express = require('express');
3
const cors = require('cors');
4
const app = express();
5
6
// Automatically allow cross-origin requests
7
app.use(cors({ origin: true }));
8
9
// Add middleware to authenticate requests
10
app.use(myMiddleware);
11
12
// build multiple CRUD interfaces:
13
app.get('/:id', (req, res) => res.send(Widgets.getById(req.params.id)));
14
app.post('/', (req, res) => res.send(Widgets.create()));
15
app.put('/:id', (req, res) => res.send(Widgets.update(req.params.id, req.body)));
16
app.delete('/:id', (req, res) => res.send(Widgets.delete(req.params.id)));
17
app.get('/', (req, res) => res.send(Widgets.list()));
18
19
// Expose Express API as a single Cloud Function:
20
exports.widgets = functions.https.onRequest(app);
Copied!

Mount an Express handler

1
exports.helloWorld = functions.https.onRequest((req, res) => {
2
res.status(200);
3
res.send('hello world');
4
});
Copied!

Firestore triggers

    onCreate
    onUpdate
    onDelete
    onWrite
1
exports.createUser = functions.firestore.document('users/{userId}').onCreate(event => {
2
// Get an object representing the document
3
// e.g. {'name': 'Marie', 'age': 66}
4
var newValue = event.data.data();
5
6
// access a particular field as you would any JS property
7
var name = newValue.name;
8
9
// perform desired operations ...
10
});
Copied!

Realtime Database triggers

    onCreate
    onUpdate
    onDelete
    onWrite
1
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original').onWrite(event => {
2
// Grab the current value of what was written to the Realtime Database.
3
const original = event.data.val();
4
console.log('Uppercasing', event.params.pushId, original);
5
const uppercase = original.toUpperCase();
6
// You must return a Promise when performing asynchronous tasks inside a Functions such as
7
// writing to the Firebase Realtime Database.
8
// Setting an "uppercase" sibling in the Realtime Database returns a Promise.
9
return event.data.ref.parent.child('uppercase').set(uppercase);
10
});
Copied!

Firebase Authentication

    onCreate
    onDelete
1
exports.sendWelcomeEmail = functions.auth.user().onCreate(event => {
2
const user = event.data; // The Firebase user.
3
4
const email = user.email; // The email of the user.
5
const displayName = user.displayName; // The display name of the user.
6
});
Copied!

Firebase Storage

    onChange
1
exports.generateThumbnail = functions.storage.object().onChange(event => {
2
const object = event.data; // The Storage object.
3
4
const fileBucket = object.bucket; // The Storage bucket that contains the file.
5
const filePath = object.name; // File path in the bucket.
6
const contentType = object.contentType; // File content type.
7
const resourceState = object.resourceState; // The resourceState is 'exists' or 'not_exists' (for file/folder deletions).
8
const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1.
9
10
// Exit if this is triggered on a file that is not an image.
11
if (!contentType.startsWith('image/')) {
12
console.log('This is not an image.');
13
return;
14
}
15
16
// Get the file name.
17
const fileName = path.basename(filePath);
18
// Exit if the image is already a thumbnail.
19
if (fileName.startsWith('thumb_')) {
20
console.log('Already a Thumbnail.');
21
return;
22
}
23
24
// Exit if this is a move or deletion event.
25
if (resourceState === 'not_exists') {
26
console.log('This is a deletion event.');
27
return;
28
}
29
30
// Exit if file exists but is not new and is only being triggered
31
// because of a metadata change.
32
if (resourceState === 'exists' && metageneration > 1) {
33
console.log('This is a metadata change event.');
34
return;
35
}
36
});
Copied!

Use ImageMagick

1
const functions = require('firebase-functions');
2
const gcs = require('@google-cloud/storage')();
3
const spawn = require('child-process-promise').spawn;
4
const path = require('path');
5
const os = require('os');
6
const fs = require('fs');
7
8
exports.generateThumbnail = functions.storage.object().onChange(event => {
9
const object = event.data;
10
11
const fileBucket = object.bucket;
12
const filePath = object.name;
13
const contentType = object.contentType;
14
15
// Download file from bucket.
16
const bucket = gcs.bucket(fileBucket);
17
const tempFilePath = path.join(os.tmpdir(), fileName);
18
const metadata = { contentType: contentType };
19
return bucket
20
.file(filePath)
21
.download({
22
destination: tempFilePath,
23
})
24
.then(() => {
25
console.log('Image downloaded locally to', tempFilePath);
26
// Generate a thumbnail using ImageMagick.
27
return spawn('convert', [tempFilePath, '-thumbnail', '200x200>', tempFilePath]);
28
})
29
.then(() => {
30
console.log('Thumbnail created at', tempFilePath);
31
// We add a 'thumb_' prefix to thumbnails file name. That's where we'll upload the thumbnail.
32
const thumbFileName = `thumb_${fileName}`;
33
const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);
34
// Uploading the thumbnail.
35
return bucket.upload(tempFilePath, { destination: thumbFilePath, metadata: metadata });
36
// Once the thumbnail has been uploaded delete the local file to free up disk space.
37
})
38
.then(() => fs.unlinkSync(tempFilePath));
39
});
Copied!
Last modified 3yr ago