I have a Firebase Cloud Function that handles some user registration information and I'm finding it to be very slow given what the function is actually doing. This function is taking approximately 6-7s to complete, routinely. I've narrowed it down to this line that's taking the most time (approximately 5s):
let snapshot = await admin.firestore().collection('users').doc(context.auth.uid).get();
if (!snapshot.exists) {
throw new functions.https.HttpsError('not-found', 'User profile could not be found');
}
90% of the time, the document being fetched should exist. I would have expected this to return incredibly fast; instead it's routinely taking about 5s to return. Any thoughts on what I could possibly be doing wrong would be appreciated.
NOTE: Everything is deployed to us-central-1
.
Here is a snippet of the logs for one of the profiling runs I made:
5:36:51.248 AM addMember Function execution started
5:36:52.256 AM addMember Checkpoint #1
5:36:52.256 AM addMember Checkpoint #2
5:36:57.253 AM addMember Checkpoint #3
5:36:57.254 AM addMember Checkpoint #4
5:36:57.597 AM addMember Checkpoint #5
5:36:57.982 AM addMember Checkpoint #6
5:36:58.051 AM addMember Function execution took 6804 ms, finished with status code: 200
The code snippet above is what is executed between Checkpoint #2
and Checkpoint #3
; it is the only lines of code between those two statements. I've executed this function repeatedly (10 times) and the average is about 5s for that block to complete.
EDIT: I've been able to narrow down the code to try and identify any bottlenecks. Here is what I've got (which still exhibits the slow behavior)
functions/index.js:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const addMember = require('./add-member');
admin.initializeApp();
exports.addMember = functions.https.onCall(addMember(admin));
functions/add-member.js:
const functions = require('firebase-functions');
const { generateCode} = require('../common');
module.exports = (admin) => async ({ email }, context) => {
console.log('Checkpoint #1')
const payload = {
code: generateCode(),
invited: new Date(),
joined: null
};
console.log('Checkpoint #2');
let snapshot = await admin.firestore().collection('users').doc(context.auth.uid).get();
if (!snapshot.exists) {
throw new functions.https.HttpsError('not-found', 'User profile could not be found');
}
console.log('Checkpoint #3');
return Promise.resolve(payload);
};