Last active
October 17, 2021 17:00
-
-
Save saintplay/3f965e0aea933a1129cc2c9a823e74d7 to your computer and use it in GitHub Desktop.
Add counter for Firestore Collection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// functions/income/counter.function.js | |
'use strict' | |
const functions = require('firebase-functions') | |
const admin = require('firebase-admin') | |
// Prevent firebase from initializing twice | |
try { admin.initializeApp(functions.config().firebase) } catch (e) {} | |
// My collection is called "incomes" | |
const incomeRef = functions.firestore.document('incomes/{incomeId}') | |
// My counter is allocated in `/counters/incomes`, maybe you wanna follow this structure instead: https://firebase.google.com/docs/firestore/solutions/counters | |
const counterRef = functions.firestore.document('counters/incomes') | |
// These references are not the same as Firestore DocumentReferences | |
// check https://firebase.google.com/docs/reference/functions/functions.firestore.DocumentBuilder | |
// Perform an increment when income is added | |
module.exports.incrementIncomesCounter = incomeRef.onCreate(event => { | |
const counterRef = event.data.ref.firestore.doc('counters/incomes') | |
counterRef.get() | |
.then(documentSnapshot => { | |
const currentCount = documentSnapshot.exists ? documentSnapshot.data().count : 0 | |
counterRef.set({ | |
count: Number(currentCount) + 1 | |
}) | |
.then(() => { | |
console.log('Incomers counter increased!') | |
}) | |
}) | |
}) | |
// Perform an decrement when income is deleted | |
module.exports.decrementIncomesCounter = incomeRef.onDelete(event => { | |
const counterRef = event.data.ref.firestore.doc('counters/incomes') | |
counterRef.get() | |
.then(documentSnapshot => { | |
const currentCount = documentSnapshot.exists ? documentSnapshot.data().count : 0 | |
counterRef.set({ | |
count: Number(currentCount) - 1 | |
}) | |
.then(() => { | |
console.log('Incomers counter decreased!') | |
}) | |
}) | |
}) | |
// Perform a fresh recount(this is expensive) when the counter is deleted (This is optional as well) | |
module.exports.recountIncomesCount = counterRef.onDelete(event => { | |
const incomesRef = event.data.ref.firestore.collection('incomes') | |
return incomesRef.get() | |
.then(querySnapshot => { | |
counterRef.set({ | |
count: querySnapshot.docs.length | |
}) | |
}) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// functions/index.js | |
/** EXPORT ALL FUNCTIONS | |
* | |
* - Loads all `.function.js` files | |
* - Supports multiple exports from a single `.function.js` file | |
* - It is optimized with `FUNCTION_NAME` env and omiting `node_modules` as well | |
* - Every function from any file must have unique name | |
* - Default export is not supported (`module.exports = ...`), instead use: `module.exports.functionName = ...` | |
* | |
* Based on this thread: | |
* https://github.com/firebase/functions-samples/issues/170 | |
*/ | |
const glob = require('glob') // npm i -S glob | |
const files = glob.sync('./**/*.function.js', { cwd: __dirname, ignore: './node_modules/**' }) | |
files.forEach(file => { | |
const functionModule = require(file) | |
const functionNames = Object.keys(functionModule) | |
functionNames.forEach(functionName => { | |
if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === functionName) { | |
exports[functionName] = functionModule[functionName] | |
} | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The
index.js
works great for me, thanks!@AntonKL I haven't tested the example function, but I'm using
admin.firestore()
to get a firestore reference.