Frank Spin
Frank Spin

Reputation: 1483

Async/Await Cloud functions for Firebase, slow performance

I need some help and support in solving a performance problem in my cloud functions for Firebase. I'm using async/await in combination with try/catch blocks to make my code more readable.

I have a simple function that writes on two locations in the database, based on params key value from a queue write event.

This simple function takes on average 1500ms to complete. Seems a little long in my opinion for a simple write to database task. I think that I made a mistake in my code and that a part of the code is not resolving correctly.

Cloud function

export const watchRegisterJobs = functions.database.ref(`queues/register/{$key}`).onWrite(
  async (event: Event<any>) => {
    if (!event.data.exists()) {
      return;
    }
    if (event.data.exists()) {
      const formData = event.data.val();
      let key;
      event.params&&(key=event.params.$key);

      if (key) {
        console.log('New user with the following id', key)
        try {
          await addUser(formData, key)
        } catch (error) {
          console.log('can not add user to database', error)
        }
        try {
          await addOrganization(formData, key)
        } catch (error) {
          console.log('can not add organization to database', error)
        }
        try {
         await event.data.ref.remove();
        } catch (error) {
          console.log('can not remove job')
        }
        return;
      }
    }
  }
)

Helper functions

export const addUser = async (data, key) => {

  const dataToSave = {
    information: ....,
    organizations: .....
  };

  try {
    return await admin.database().ref(`users/${key}`).set(dataToSave);
  } catch (error) {
    return error;
  }
}

export const addOrganization = async (data, key) => {
  const organization = {
    ...
  }
  try {
    return await admin.database().ref(`organizations/${key}`).set(organization);
  } catch (error) {
    return error;
  }
}

Update Based on the comments I have made some improvements to the code. Performance is still the same, but code looks better.

Cloud function

export const watchRegisterJobs = functions.database.ref(`queues/register/{$key}`).onWrite(
  async (event: Event<any>) => {
    if (!event.data.exists()) {
      return;
    }

    const formData = event.data.val();
    let key;
    if(event.params) {
      key = event.params.$key;
    }

    if (key) {
      console.log('New user with the following id', key)
      try {
        await addUser(formData, key)
        await addOrganization(formData, key)
        await event.data.ref.remove();
      } catch (error) {
        console.log('can not write to the database', error)
      }
      return;
    }
  }
) 

Helpers

export const addUser = (data, key) => {

  const dataToSave = {
    information: ....,
    organizations: ....
  };

  return admin.database().ref(`users/${key}`).set(dataToSave);
}

export const addOrganization = (data, key) => {
  const organization = {
    ...
  }

  return admin.database().ref(`organizations/${key}`).set(organization);
}

Upvotes: 0

Views: 2740

Answers (1)

DarkNeuron
DarkNeuron

Reputation: 8692

Seeing as your code looks alright (I'm not seeing any codepaths that doesn't return), I just did my own test with async await, and here are my results:

  1. execution (after a code update and deploy): 1058ms
  2. execution: 120ms
  3. execution: 38ms

I suspect that you are running into a cold-start of your functions. The first time you execute a function after a code update, Firebase needs to setup the environment, which takes a while the first time. The same happens when the function hasn't been used for a while.

More info here by one of the devs: Firebase cloud functions is very slow

EDIT: Forgot to mention that I'm using typescript. Meaning my code will obviously be transpiled, as Firebase doesn't natively support async/await yet. I suspect you are doing something similar.

Upvotes: 1

Related Questions