-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
64 lines (57 loc) · 2.43 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
var Firebase = require('firebase');
var async = require('async');
// Extract data from the kinesis event
exports.handler = function(event, context) {
// This function abstracts the expected structure of any Kinesis payload,
// which is a base64-encoded string of a JSON object, passing the data to
// a private function.
function handlePayload(record, callback) {
encodedPayload = record.kinesis.data;
rawPayload = new Buffer(encodedPayload, 'base64').toString('utf-8');
handleData(JSON.parse(rawPayload), callback);
}
// The Kinesis event may contain multiple records in a specific order.
// Since our handlers are asynchronous, we handle each payload in series,
// calling the parent handler's callback (context.done) upon completion.
async.eachSeries(event.Records, handlePayload, context.done)
};
// This is just an intermediate function. The projectId is buried in an
// analyticsId of the format clientId-projectId-version. So the string split
// extracts the projectId.
function handleData(data, callback) {
var projectRef = getProjectRef();
var analyticsId = JSON.parse(data.properties).analyticsId;
var projectId = analyticsId.split('-')[1]
incrementProjectEvent(projectRef, projectId, data.event, callback);
};
// Lambda does not have access to environment variables, so we hardcode the
// production db URL into the codebase (this is non-sensitive) but override
// with local environment variables for development and test.
function getProjectRef() {
var prodFirebaseUrl = 'https://luminous-heat-2841.firebaseio.com/';
var firebaseUrl = process.env.FIREBASE_URL || prodFirebaseUrl;
return new Firebase(firebaseUrl + 'project/');
};
// Incrementing a value is an atomic operation, meaning that you need to know
// the current value in order to add to it, and multiple set operations cannot
// be executed at the same time. Firebase provides for this using transactions.
//
// As long as the callback is executed on completion of the transaction, you
// are in good shape.
function incrementProjectEvent(projectRef, projectId, eventName, callback) {
projectRef
.child(projectId)
.child('events/' + eventName)
.transaction(function(currentData) {
if (currentData === null) {
return 1;
} else {
return currentData + 1;
}
}, function(error, committed, snapshot) {
if (error) {
console.log('Transaction failed abnormally!', error);
}
callback();
});
};