Ajay G
Ajay G

Reputation: 43

Google Cloud Function sometimes works and sometimes not

I'm using a onCreate function for Firestore to detect user signup and create a document using his user id. The problem is the function works sometimes and doesn't work other times. Also, I'm getting a "Function returned undefined, expected Promise or value" error all the time whenever the function run. I have tried many solutions which were given on similar questions but still no luck.

export const createNewUser = functions.auth.user().onCreate(user => {
  const userId = user.uid;

  const updateData = {
    ads_watched: 0,
    coins: 20000,
    gems: 0
  };

  admin.firestore().doc("cashon/" + userId)
  .set(updateData)
  .then(writeResult => {
      console.log("User Created result:", writeResult);
      return null;
  })
  .catch(err => {
      console.log(err);
      return null;
    });
});

Upvotes: 0

Views: 338

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83093

You need to return the promise returned by the set() asynchronous method, as follows:

export const createNewUser = functions.auth.user().onCreate(user => {
  const userId = user.uid;

  const updateData = {
    ads_watched: 0,
    coins: 20000,
    gems: 0
  };

  return admin.firestore().doc("cashon/" + userId)
  .set(updateData)
  .then(() => {
      console.log("User Created result:", writeResult);
      return null;
  })
  .catch(err => {
      console.log(err);
      return null;
    });
});

As indicated by the "Function returned undefined, expected Promise or value" error, you MUST return a Promise or a value in a background triggered Cloud Function, to indicate to the platform that the Cloud Function is finished. Since you are not returning a Promise, you encounter this inconsistent behaviour: sometimes the Cloud Function is killed by the platform before it has written to Firestore.

I would suggest you watch the 3 videos about "JavaScript Promises" from the Firebase video series by Doug Stevenson (https://firebase.google.com/docs/functions/video-series/), which explain this key point.

Also, note that the set() method returns a Promise<void>.

And, finally, note that if you don't need the console.log("User Created result:", writeResult);, you may do as follows:

export const createNewUser = functions.auth.user().onCreate(user => {
  const userId = user.uid;

  const updateData = {
    ads_watched: 0,
    coins: 20000,
    gems: 0
  };

  return admin.firestore().doc("cashon/" + userId)
  .set(updateData)
  .catch(err => {
      console.log(err);
      return null;
    });
});

Upvotes: 1

Related Questions