0

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);
};
themanatuf
  • 2,880
  • 2
  • 25
  • 39
  • Please edit your question to include how you tested the performance. I highly recommend including both the default logging output, and adding custom logging and its output. Also note that the snippet you've shared is not a Cloud Function, so we have no way to comment on how this performance relates to Cloud Function based on that. – Frank van Puffelen Jun 29 '20 at 15:13
  • Log snippet added. Unfortunately I cannot post the whole function code, but take the leap of faith that what I said is accurate. – themanatuf Jun 29 '20 at 19:51

1 Answers1

0

For what it's worth, I came across these which has been helpful. The speed of the functions isn't quite what I expect/hoped for and I'm starting to lean towards it being the CPU speed of the instance (128MB). Regardless, hopefully someone else finds these posts useful:

https://stackoverflow.com/a/47985480/541277 https://github.com/firebase/functions-samples/issues/170#issuecomment-323375462

themanatuf
  • 2,880
  • 2
  • 25
  • 39